Facebook
Twitter
Google+
Kommentare
26

JavaScript-Komprimierung

Zuerst möchte ich alle informieren, dass wir jetzt einen neuen RSS-Feed haben und zwar einen, der alle phm|network Beiträge rauslöscht. Das wurde ja gefordert (auch von mir) und tadaaaa einen Tag später gibt es das Feature schon. Wenn das doch immer nur so schnell bei mir gehen würde.

Aber jetzt zum eigentlichen Thema: JavaScript-Komprimierung. Ich hatte vor kurzen, also so vor ca. 3 Jahren, eine Diskussion mit Sebastian aus meinem ehemaligen Team, ob wir JavaScript-Komprimierung bei uns im Intranet einsetzen. Ich war dagegen. Ich finde man sollte so lange wir möglich auf irgendwelche Optimierungsmaßnahmen verzichten, solange sie nicht vonnöten sind. Oder wie heißen die beiden Regeln der Optimierung:

  1. Don’t do it
  2. Don’t do it yet (for experts only)

Wir hatten damals ein internes Netz und es war egal, wie groß die JavaScript-Dateien waren. Das Netz war schnell. Ich befürchte, dass die wenigsten von uns Webseiten betreiben, die wirklich unter ihrer Last zusammenbrechen. Nehmen wir aber mal an, wir komprimieren unseren JavaScript-Code … einfach weil wir es können. Ich finde das debuggen wird damit auf einmal so viel schwieriger. OK ich gebe zu, man hat ein Staging-System und auf dem wir alles vorher getestet und wahrscheinlich auch ohne JavaScript-Komprimierung, aber wenn dann doch etwas nicht klappt, dann kann man mit dem Obfuscated Code nicht so viel anfangen.

Ich finde es aber total legitim eine third-party-Komponente. Ich habe zum Beispiel jQuery als solche eingebunden. Ich gehe nämlich von aus, dass es funktioniert und wenn nicht, dann kann ich da eh nichts machen.

Was ich aber eigentlich mit diesem Artikel sagen will. In vielen Fällen komprimiert man das JavaScript nicht weil man es muss, sondern weil es hip ist. Man sollte sich überlegen, ob es vielleicht eine Lösung für ein Problem ist, das man gar hat.

Bei großen Hochtraffic Anwendungen/Seiten kann es natürlich auch mal sein, dass es wirklich nötig ist. Dafür gibt es Tools, die einem bei der Komprimierung helfen. Die will ich euch auch bald vorstellen, da ich hierfür heute lwider keine Zeit mehr habe. Vielleicht will ja auch jemand von euch was schreiben. Wer weiß.

Über den Autor

Nils Langner

Nils Langner ist der Gründer von "the web hates me" und auch der Hauptautor. Im wahren Leben leitet er das Qualitätsmanagementteam im Gruner+Jahr-Digitalbereich und ist somit für Seiten wie stern.de, eltern.de und gala.de aus Qualitätssicht verantwortlich. Nils schreibt seit den Anfängen von phphatesme, welches er ebenfalls gegründet hat, nicht nur für diverse Blogs, sondern auch für Fachmagazine, wie das PHP Magazin, die t3n, die c't oder die iX. Nebenbei ist er noch ein gern gesehener Sprecher auf Konferenzen. Herr Langner schreibt die Texte über sich gerne in der dritten Form.
Kommentare

26 Comments

  1. JavaScript zu komprimieren ist aus meiner Sicht mehr als eine Modeerscheinung. Im Intranet fällt es durch das schnelle Netz vielleicht nicht auf, aber in der „echten“ Welt schon eher.

    Gerade bei mehreren Scripten auf der Seite, weil sich gleichzeitig auch die Anzahl der Requests damit senken lässt. Wenn die Anwenung ordentlich umgesetzt ist, dann bleibt sie im Entwicklermodus auch immernoch leicht debugbar.

    Reply
  2. würde es nicht reichen z.B. bei Apache mod_deflate zu aktivieren? das laeuft weitgehend transparent und man muss das rad nicht zweimal erfinden…

    Reply
  3. Habe es kürzlich erst bei einem Projekt eingesetzt in Zusammenspiel mit einem „JS-Provider“, der seitenabhängig die richtigen Javascriptdateien zusammenstellt und ausspielt. Könnte ich gerne etwas drüber schreiben, wenn es niemandem was ausmacht, dass der Code in Java geschrieben ist 😉

    Was man nicht außer acht lassen sollte ist auch, dass beispielsweise der YUICompressor von Yahoo! die Kommentare rausfiltert. Da macht es dann doch schon Sinn ein solches Geschoss einzusetzen, nicht immer will man die Entwicklerkommentare in seinem Live-Code haben. Ich finde deshalb schon, dass die Kompression durchaus Sinn macht.

    Reply
  4. Wir haben sehr gute Erfahrungen mit der on-the-fly Komprimierung auf den Live-Servern gemacht. Der JS-Code wird nach verschiedenen Kriterien bestmöglich zusammengefasst, minifiziert, gepackt und gecached. Nur bei Versionswechseln, werden dann die Dateien wieder neu generiert.
    Auf unserem Dev-System liegt unser JavaScript komplett und kommentiert vor und wird auch genauso auf unsere Live-Server hoch geladen.
    Wenn auf »Fremd-Servern« installiert wird, werden von uns allerdings teilweise minifizierte und vor-gepackte JS-Dateien installiert. Kommt dann immer darauf an, was mit dem Kunden vereinbart wurde.

    Reply
  5. Ich stimme ar zu: mod_deflate und mod_expires lassen sich schnell und einfach aktivieren und machen JavaScript Kompression überflüssig (ich habe da auch mal drüber gebloggt: http://blog.aditu.de/2009/08/22/mehr-performance-mit-mod_deflate-und-mod_expires/).

    Es ist halt auch immer eine Frage wie groß der Nutzen ist. Jede Maßnahme, die den Ladevorgang der Seite verringert und damit die User-Experience verbessert, ist legitim (wobei ich jetzt mal offen lasse, ob man da viel heraus holt, wenn man eine Hand voll JavaScript Dateien komprimiert).

    Grüße
    Tobi

    Reply
  6. Also sorry, aber ich kann diesem Artikel so überhaupt nicht zustimmen. JS Komprimierung (und wenn es nur die Entfernung von unnötigem Whitespace ist) reduziert die Datenmengen massiv. Das kommt dem Server zugute (weniger Traffic, schnellere Abarbeitung der Requests) so wie dem Client (schnelleres Laden der Seite und speziell im Mobil-Sektor auch Schonung des Akku durch kürzere Verbindungszeit).
    Wenn man nur diese kleine Komprimierung verwendet dann leidet auch der Code nicht oder wird ungültig, lediglich lesbar ist er nicht mehr besonders. Das sollte in der Produktivumgebung aber ohnehin egal sein.

    Man muss nicht immer gleich high-traffic Seiten betreiben damit sich das Thema lohnt, denn Nachteile sehe ich ehrlich gesagt dabei keine…

    Jsut my 2 cent…

    Reply
  7. Ich überlege gerade was der Artikel mir sagen soll. Anscheinend geht man davon aus, dass man das JavaScript zur Entwurfszeit komprimiert und nicht vollautomatisch im Build-Prozess (1. Fehler). Sowie, dass man sich keine Kopie der Originalquellen zurückbehält (2. Fehler).
    Solange man diese zwei Probleme vermeidet, finde ich die Argumente des Autors haltlos.

    Reply
  8. Moin,
    also JS-Komprimierung hin oder her. Deutlich mehr brachte bei einigen High-Performance-Projekten von mir der Einsatz von allgemeiner gzip-Komprimierung via „mod_deflate“ und das setzen von Cache-Headern mit „mod_expires“.
    Die Performance steigt um einen deutlich höheren Prozentsatz, als das reine komprimieren von JS-Dateien. Damit könnte man sicherlich auch nochmal das ein oder andere Prozent an Performance herausholen, aber deutlich mehr bringt da meineserachtens die oben genannten Apache-Module (vorausgesetzt, man nutzt natürlich einen Apache). Die beiden verringern nämlich nicht nur den Traffic, sondern entlasten auch zusätzlich den Server, sodass dieser mehr Requests verarbeiten kann.

    Und wer wirklich die Performance nochmal deutlich mehr steigern will, als über JS-Komprimierung sollte sich über ein Caching-Framework Gedanken machen, damit zumindest die statischen Teile der Website nur noch als HTML ausgeliefert werden und nicht noch PHP ausführen oder Datenbankabfragen generieren. Deshalb halte ich persönlich auch nicht so viel vom komprimieren der eigenen Javascripte – solche fertigen Bibliotheken wie jQuery und wie sie nicht alle heißen würde ich natürlich trotzdem immer in der minified-Version nutzen. Die möchte ich in aller Regel aber auch nie debuggen.

    Hier die Links dazu:
    http://httpd.apache.org/docs/2.0/mod/mod_deflate.html
    http://httpd.apache.org/docs/2.0/mod/mod_expires.html

    Reply
  9. Javscript Komprimierung macht genau dann Sinn, wenn man beispielsweise keine Traffic-Flat auf seinem Server hat. jQuery beispielsweise ist um einiges kleiner wenn man es komprimiert anbietet.

    Am besten merkt man die Performance auf gutbesuchten Seiten, beispielsweise Onlineshops. Bei Magento spürt man das meines Erachtens am meisten. Bei 100 Usern am Tag (mal eine kleine Zahl für einfachere Rechnung) spart man da schnell ein paar MB an Traffic. Der User der vor dem Computer sitzt wird es einem Danken wenn alle hippen Web2.0 Features binnen kürzester Zeit verfügbar sind.

    Auf meinen Testservern habe ich auch nur unkomprimierte Scripts herumliegen, aber auf Produktivservern sollten nur komprimierte Dateien angeboten werden, entweder vorab-komprimiert oder on-the-fly.

    Reply
  10. Was für viele sicher auch ein wichtiger Grund ist ihren JS-Code zu obfuscaten ist dass sie ihren Code schützen wollen. So kann man ihn einfach nicht so schnell klauen.

    Reply
  11. Hallo,

    ich sehe das wie Philip. Die Komprimierung von zu übertragenden Code liegt meiner Meinung nach nicht im Aufgabenbereich der übertragenen Applikation, als viel mehr in der übertragen_d_en Applikation (Webserver). Die beschäftigt sich schon viel länger und bestimmt auch effektiver mit dem Thema und setzt auf einem ganz anderen Level an. Die Verschlüsselung überlässt man ja auch OpenSSL – also jemandem, der etwas davon versteht.

    Reply
  12. Ich sehe das Hauptproblem jetzt gar nicht mal unbedingt in der Dateigröße, sondern in den Roundtrips. Webanwendung benutzen heutzutage immer komplexeres JavaScript. Da gebieten es die Regeln für sauberen Code den Quelltext logisch auf viele Module und Dateien zu verteilen. Ein aktuelles Projekt von mir benötigt zur Zeit 50+ JS-Dateien. Wenn der Browser die alle einzeln abholen soll, verzögert das den Seitenaufbau erheblich.
    Da man dann folgerichtig sowieso einen Build-Prozess für JS braucht, kann man auch gleich noch Komprimierung mit einbauen.

    Ich empfehle einen Blick auf die Closure Tools von Google. Deren Compiler optimiert den Code auf der (leider nicht ganz unproblematischen) höchsten Einstellung sogar noch durch dead code removal und code inlining.

    Reply
  13. @Philip
    Komprimierung von Javascript (und CSS) schließt doch eine Nutzung des deflate & Expires-Moduls nicht aus. Beide ergänzen sich. Im übrigen ist deine Aussage falsch, dass durch den Einsatz der Module die Server entlastet werden. Wer ist denn für die Komprimierung der Dateien zuständig? Der Websever…

    Auch ein Caching-Framework, also Erzeugung von statischen Resourcen, ergänzt sich doch super mit JS- und CSS-Komprimierung. Das sind ja auch zwei vollkommen unterschiedliche Themenfehler (einmal die Seite und einmal die statischen Resourcen dazu). Ein komplettes Caching von Seiten ist bei den meisten Seiten eh kaum möglich aufgrund von Login-Status, Warenkorb usw. Mit intelligenten Caching kann man da sicherlich etwas rausholen, aber das widerspricht sich nicht!

    Was ich vor allem nicht verstehe: Wenn man das Expires-Modul nutzt, muss man sich Gedanken beim Build-Prozesse der statischen Resourcen machen sonst bekommt man dort ja Probleme wenn man eine neue Version deployt. Und in diesem Buildprozess ist doch ein YUI-Kompressor sehr einfach integriert. Deutlich einfacher als das Renamen der statischen Resourcen per Deployment-Version.

    Und wer debuggt bitte auf dem Live-System im JS herum? Da kann ich doch gleich die Fehlermeldungen bei PHP anstellen und auf den Live-Server programmieren. Das ist für mich kein Argument!

    P.S. Für diesen Blog würde ich mich wahrscheinlich auch sparen, die statischen Dateien zu komprimieren, ich würde aber wohl genauso wenig das Expires-Modul einsetzen. Für größere Seiten / die Arbeit wäre das aber einer der ersten Optimierungsschritte.

    P.P.S. Vor allem für DSL 386k-Nutzer bzw. ISDN-Surfer macht das erhebliche Unterschiede. Die Erfolge bei kleineren Datenmengen sind auch gut messbar. Den 100MBit-Nutzer interessiert das natürlich nicht. Dies betrifft aber auch Expires & GZIP! 🙂

    Reply
  14. Auch wenn die Liste hier schon lang ist, ein Kommentar muss sein. 🙂

    Mir werden hier zu viele Themen in einen Topf geworfen und teilweise auch komisch dargestellt.

    Obfuscating:
    Obfuscated-Code hat rein gar nichts mit verkleinerten Javascripts zu tun. Beim Obfuscating geht es darum den Code so zu entstellen, dass er nicht mehr ohne Wissen entworren werden kann. Beim verkleinern werden lediglich unnötige Zeichen entfernt. Die Lesbarkeit bleibt dabei aber zu 100% erhalten!

    Verkleinern:
    Code zu verkleinern, sollte für jede Webseite Pflicht sein! Es geht immerhin nicht nur darum, wieviele Nutzer ein Portal hat. Ich betreibe eine Webseite, die hat an guten Tagen einen Besucher. Es werden aber täglich einige hundert Seiten abgefragt. Man optimiert immerhin nicht nur für echte Nutzer sondern auch für die hunderte Bots, die so ein schönes Grundrauschen auf den Server zaubern.
    Außerdem sollte jedes BIT gespart werden, es verkürzt die Ladezeit, die Übertragungsrate, den Stromverbrauch bei Client, Server und sonstiger Infrastruktur und so weiter. Nur weil eine Seite wenig besucht wird, sollte man an dieser Stelle nicht unbedingt sparen. Soviel Aufwand ist das Verkleinern, dank der nötigen Tools nicht mehr.

    Kompression:
    Durch Kompression wird Script per gzip verkleinert. Es sollte ebenfalls in jedem Fall genutzt werden, weil sich dadurch unnötige Datenmengen vermeiden lassen. Kompression ist in weniger als 2 Sekunden eingeschalten. Es Bedarf lediglich einer Zeile in der .htaccess, wen es nicht global im Apache eingestellt wird. Das Modul sollte ja auf jedem normalen Webhosting vorhanden sein.

    Expire-Header:
    Auch der Expire-Header ist per .htaccess in wenigen Augenblicken eingestellt. Man erledigt dies einmalig, hat also einen sehr geringen Aufwand und den auch noch einmalig, warum sollte man dabei sparen??
    Die einzigen Webseiten, die diesen Headereintrag sparen können, haben nur eine einzige Seite, die man sich auch nur einmal ansehen will … Immer dann, wenn eine Seite mehr als eine PageImpression erwarten lässt, sollte man auf diesen Eintrag zurückgreifen und Übertragungen sparen!

    Selbst im Intranet, wo alles so schön schnell ist, sollte man es ruhig anwenden. Neben dem Stromverbrauch, entlastet man in der Regel (außer gzip) den Webserver. Auch im Intranet gibt es hin und wieder Stoßzeiten. Erst zu reagieren, wenn es brennt ist der blödest Ansatz im Risk-Management. Der nötige Mitarbeiter ist an dem Tag eh im Urlaub oder krank und alles geht den Bach runter … 🙂

    Reply
  15. Wow, da hast du ja in ein Wespennest gestochen 😀

    Ja, ich sehe es nach wie vor als sinnvoll, JS zu komprimieren. Aber nicht unbedingt Einzeldateien. Wirklich sinnvoll ist es, mehrere JS sourcen zusammenzupacken, komprimieren und als eine Datei auszuliefern, um die Anzahl der Requests des Clients zu minimieren.

    Reply
  16. @ Sebastian:

    Welchen Vorteil hat es denn einzelne Skripte zu komprimieren? Teuer sind doch gerade die zusätzlichen Requests. Ressourcen zu einer großen Ressource zusammen packen ist wirklich ein Geheimtipp, wenn es um Performance geht.

    Kennt ihr Dojo? Wer jemals eine Anwendung mit Dojo gebaut hat, wird das Dojo Buildsystem kennen:

    In Dojo ist jede „Klasse“ ja in einer eigenen Datei untergebracht.
    Es gibt Templates, die auch in eigenen Dateien liegen.

    Über dojo.require() kann ich sagen, welche Klasse ich benötige. Dojo lädt sie mir (eine Art Autoloader) per XHR.

    Das Problem:
    Die zusätzlichen XHRs kosten (siehe oben: Jeder Request richtig teuer – es ist heute billiger, fast 1MB in einem Request zu laden, als 10 Requests â 10kb durchzuführen. Denkt dabei auch an Verbindungen, mit schlechter Latenz).

    Die Lösung bei Dojo:
    Layer! Ich baue mir bspw. ein Layer „myApp.js“ in der ich alle von meiner Anwendung benötigen Klassen per Require einbinde. Diese „myApp.js“ ist es auch, die per Header einbinde – sprich ich habe nur eine einzige Datei, und dann steht mir alles zur Verfügung.

    Für die Produktion „baue“ ich dann besagten Layer:
    Dabei geht das Buildsystem hin und inkludiert alle Ressourcen in einer großen Datei (meinem Layer). Sprich die Require-Calls werden durch den Code der entsprechenden Klasse ersetzt. Gleiches kann mit CSS-Styles geschehen.

    Typische Anwendungen kommen so auf eine 500-900kb große Datei. Diese kann nun vom Buildsystem zusätzlich verkleinert werden:
    – Leerzeichen entfernen
    – Kommentare entfernen
    – Substitution

    Das ist aber granular einstellbar.

    So erhält man also eine 200-300kb große Datei. Wird diese nun über GZIP/mod_deflate übertragen, kommt sie auf 80-90kb. Was will man mehr?

    Setzt man, wie von butzi erwähnt jetzt noch richtige Caching-Werte, flutscht es nur noch.

    => Diese Art von „Komprimierung“ finde ich völlig legitim und ein MUSS.

    Mehr zum Dojo Buildsystem gibt es hier: http://docs.dojocampus.org/build/index

    Wer hingegehn auf Komprimierung zurückgreift, um das Skript zu schützen, sollte endlich mal in der Realität aufwachen. Es gibt heute gute De-Komprimierer, die den Code fast noch lesbarer machen, als das Original 😉

    Außerdem kann das zu Problem führen – in meinen Augen zu Recht:
    http://www.heise.de/newsticker/meldung/Finger-weg-von-JavaScript-Packern-215644.html

    Reply
  17. @Ulf Kirsten:
    Stimmt, die Last des Servers wird nicht geringer, wenn eine Datei angefordert wird. Aber mit dem mod_expires verhindert man ja eben, dass die Datei überhaupt angefordert wird vom Server.
    Mit mod_deflate erhöht man sogar die Serverlast kurzzeitig, da natürlich hier der Server die Komprimierung übernimmt. Wobei ich das „tiefer im System“ verankerte mod_deflate, einfach vom Gefühl her, für schneller halte als irgendwelche Scripte. mod_deflate ist natürlich erst in Verbindung mit einem Caching-Mechanismus so richtig sinnvoll. Dann wird die Komprimierung nämlich nur einmal durchgeführt und dann wird auf den Cache zurückgegriffen, was natürlich deutlich weniger Last erzeugt, als die Komprimierung.

    Reply
  18. So, es braucht neben meinem gestrigen Kommentar auch noch einen konstruktiven 😉

    Meine Ansichten sind: Eine echte Komprimierung darf man in bei Verfügbarkeit von GZip & Co. ausser acht lassen, wenn es dabei eben nur um die Dateigröße geht. Mit „echter Komprimierung“ meine ich wirkliches Umschreiben des Codes, Abkürzungen, Vereinfachungen.. eben das Minifizieren. Denn dabei hält man sich die Lesbarkeit noch ein Stückchen offen, weil: Minifizieren und GZip beißt sich zwar nicht, aber letzteres ist nicht mehr sehr effizient möglich.

    Drei Dinge sind aber unerlässlich: Whitespaces/Kommentare sollten für das Live-System ausgefiltertet sein (unnötige Daten, selbst komprimiert), Einzeldateien sollten zusammengefasst werden (unnötige bzw. sogar unmögliche Requests) und eine Trennung mindestens zwischen Dev- und Prod-Umgebung.

    Ob man jetzt über den Buildprozess den Google Closure Compiler o.ä. anwirft und fertige Ein-Script-Files baut oder mit echten oder semi-on-the-fly-Tools arbeitet, ist jedem selbst überlassen. Bei meinem aktuellen Java-Projekt bin ich von Closure Compiler zu JSO (http://js-optimizer.sourceforge.net/) gewechselt: a) Maven-kompatibel und b) mit o.g. Möglichkeiten wie das Erstellen von Gruppen („Layer“).

    Zu guter Letzt: Es kommt immer auch drauf an, was für eine Art Applikation man da hat. O.g. Java-Projekt ist eine RIA mit ExtJS, d.h. wir kommen zusammengepackt auf etwa 1.4 MB Javascript. Da ist GZip/Deflate Pflicht wie auch das logische Verknüpfen von Gruppen/Paketen. Echtes Minifizieren ist manchmal nicht immer möglich oder schwierig bei so großen Anwendungen (Namespace-Problematik, Stichwort „Externals“).

    Übrigens: Nicht weit so schlimm, aber auch von dem Problem betroffen: CSS. Vergisst man immer mal schnell; leider sind CSS-Dateien unterschiedlicher Pfade erheblich schwerer zusammenzufassen.

    Reply
  19. @Philip
    Erst jetzt deinen Kommentar von Freitag gesehen. Deine Ausführungen sind absolut richtig, aber gerade die Komprimierung (& Vereinigung) von statischen Resourcen spart noch einmal Serverlast wenn man dies im Buildprozess macht, da der Server ja dann weniger kB komprimieren und ausliefern muss. Und insbesondere wenn man Expires-Header nutzt, muss man irgendwie einen Buildprozess haben (sei es automatisiert oder manuell) wo man ohne viel Aufwand die Komprimierung mit einbinden kann. Als 1.Optimierungsmaßnahme würde ich mir natürlich auch die 5 Minuten nehmen und mod_deflate aktivieren, dann kommt aber auch schon die Komprimierung zusammen mit den Expires-Headern.

    Reply
  20. mal etwas anderes: Danke für die Trennung zum php|network
    ich hatte schon andere Blogs aus dem Network abonniert, und somit doppelt 🙂

    Zum Wespennest:
    Früher lag das Problem vom Traffic, Server- und Client-Belastung nicht beim Programmierer, mittlerweile hat man sehr viel Einfluss darauf.

    Ich persönlich bin ja eher der Performance-Freak.
    Traffic-Sparen geht auf kosten von Performance, und umgekehrt.
    Hier sind wir also bei der gleichen Frage wie: Lebe ich um zu Arbeiten, oder Arbeite ich um zu Leben 😉

    In diesem Sinne: frohes Arbeiten 🙂

    Juan

    Reply
  21. Related: Vortragsfolien “Frontend-Performance (mit PHP)” von Nico Steiner & Frank Kleine sind online (PHPUG Karlsruhe).

    Und wer wirklich wissen will was im Browser abgeht (hier Mozilla): Faster HTML and CSS: Layout Engine Internals for Web Developers, behandelt auch die Wirkungen von Javascripts (via Let’s make the web faster).

    Nicht zu früh mit dem optimieren anzufangen halte ich sicherlich für sinnvoll. Es fangen ja auch die wenigsten an, ihre Webanwendungen in C zu schreiben weil das so nah an die Performance von statischen Seiten kommt.

    Reply

Leave a Comment.

Link erfolgreich vorgeschlagen.

Vielen Dank, dass du einen Link vorgeschlagen hast. Wir werden ihn sobald wie möglich prüfen. Schließen