Die letzten zwei Artikel der WordPress Performance Guideline haben gezeigt, wie man aus Sicht der Web Performance Optimierung (WPO) am besten externe CSS- und JavaScript-Dateien einbindet. Doch warum soll man den jeweiligen Code denn überhaupt in eine externe Datei auslagern? Würde es nicht mehr Sinn machen, wenn man sämtlichen Code einfach im HTML-Dokument einbettet und dadurch zahlreiche HTTP Requests spart?
Dieser Artikel ist Teil der Guideline WordPress Performance.
Spätestens seit dem Zeitpunkt wo Google sein PageSpeed Insights Tool um eine Bewertung für Mobilgeräte ergänzt hat, ist das Thema Inlining von CSS- und JavaScript-Code wieder in den Fokus zahlreicher Webentwickler geraten. Doch warum? Folgender Verbesserungsvorschlag gab den Auslöser
Behebung erforderlich: JavaScript- und CSS-Ressourcen, die das Rendering blockieren, in Inhalten „above the fold“ (ohne Scrollen sichtbar) beseitigen
Das heißt umformuliert: Sowohl externe CSS- als auch externe JavaScript-Dateien blockieren das Rendering (also den Aufbau und die Darstellung der Webseite im Browser), wie in den Artikeln Wie und wo soll man CSS in HTML einbinden? und Skripte am Ende laden bereits gezeigt wurde. Die übliche Vorgehensweise das Problem zu lösen: Alles was „above the fold“ ist, also der Bereich einer Webseite der für den Nutzer auf den ersten Blick ohne scrollen sichtbar ist, sollte direkt im HTML-Dokument (also inline) hinterlegt werden.
Machen externe CSS- und JavaScript-Dateien dann noch Sinn?
Diese Frage ist aufgrund der aktuellen Entwicklungen durchaus gerechtfertigt, vor allem für den mobilen Bereich wo die Latenzen hoch und die Bandbreite niedrig ist. Im Extremfall könnte man versuchen sämtlichen Code inline im HTML-Dokument zu platzieren, was einige Vorteile mit sich bringen würde:
- Zusätzliche HTTP Requests (siehe Reduzierung von HTTP Requests) werden vermieden
- Das Zusammenführen von CSS- und JavaScript-Code in eine eigenständige Datei wird überflüssig
- Sämtlicher Code wird sofort mit dem HTML-Dokument mitgeliefert, weshalb das Rendering der Seite umittelbar gestartet werden kann
Dieses Vorgehen hat allerdings auch Nachteile, die je nach Webseite gegenüber den Vorteilen abgewogen werden müssen:
- Das HTML-Dokument wird in der Regel nicht oder nur sehr kurz (10 Minuten) gecacht. Das führt dazu, dass die Ladezeit für den Repeat View (wiederholter Seitenaufruf) unter Umständen steigt (weitere Informationen zum WordPress Browser Caching)
- Inline JavaScript hat ein anderes (schlechteres) „Blocking-Verhalten“ im Vergeich zu externen JavaScript-Dateien
- Kein Load On-Demand (nähere Infos in den weiterführenden Links)
Um auf die Ausgangsfrage in der Überschrift zurückzukommen: Externe Dateien machen immer noch Sinn, vor allem bei Webseiten mit mehreren Pageviews pro Session wo die Nutzer dann im Idealfall die externen CSS- und JavaScript-Dateien direkt aus dem Browser Cache laden können. Eine Studie bei Yahoo! aus dem Jahre 2007 (mir ist leider keine neuere Studie bekannt) hat gezeigt, dass etwa 40 – 60 Prozent (abhängig von der Yahoo!-Seite) der Anwender die jeweilige Seite mit einem gefüllten Cache besuchen. Bei den Seitenaufrufen (ein Anwender kann mehrere Seiten besuchen) sind es sogar 75 – 85 Prozent, wo Ressourcen direkt aus dem Browser Cache geladen werden können und kein zusätzlicher HTTP Request nötig ist.
Allerdings macht auch genau das gegenteilige Vorgehen, nämlich alles als Inline-Code zu platzieren, durchaus Sinn, da dadurch eventuell die Ladezeit sowie die StartRender-Zeit reduziert werden kann. Die Frage, ob nun Inline oder External JavaScript / CSS besser ist, kann damit also nicht pauschal beantwortet werden, sondern muss im Einzelfall ausführlich getestet werden. Die ideale Lösung würde aber eine Mischung aus beiden Welten, sowohl Inline-Code als auch externen Dateien, darstellen.
Die ideale Lösung – Der Garten Eden
Wie schwer es ist im Paradies zu bleiben das mussten bereits Adam und Eva feststellen. Ebenso schwer ist es auch die ideale Lösung – den Garten Eden – für die eigene Webseite abzubilden oder ihm zumindest nachzueifern. Denn verbindet man das Beste aus beiden Welten, Inline und External CSS- und JavaScript, dann würde die optimale Lösung wie folgt aussehen:
Für jede einzelne Seite wird – abhängig von der Größe des „above-the-fold“-Bereichs – der benötigte CSS- und JavaScript-Code direkt in das HTML-Dokument serverseitig eingefügt. Alle Elemente die nicht in diesen Bereich fallen, werden anschließend – ohne den parallelen Download oder das progressive Rendering zu blockieren – nachgeladen.
Für viele Webseitenbetreiber wird diese Vorgehensweise aber leider eine Wunschvorstellungen bleiben, solange keine automatisierte Lösung (welche mir für WordPress bis jetzt nicht bekannt ist) existiert. Eine gute aber nicht optimale Lösung – thematisch getrennt in JavaScript und CSS – gibt es allerdings trotzdem.
Rendering blockierendes JavaScript entfernen
Das ist die leichteste der beiden Aufgaben. Wie im vorherigen Teil dieser Artikelserie bereits gezeigt, verhindert eine Platzierung von externen JavaScript-Dateien am Ende des HTML-Dokuments (vor dem schließenden BODY-Tag) eine Blockierung des Renderings als auch die Blockierung des Downloads von weiteren Elementen der Webseite. In den meisten Fällen sollte das recht einfach umzusetzen sein, womit das Problem dann auch gelöst wäre.
Ist es nicht möglich den kompletten JavaScript-Code im HTML-Dokument nach unten zu verlagern, dann muss der im HEAD-Bereich benötigte Code vom restlichen JavaScript extrahiert und im HEAD-Bereich inline (mit dem SCRIPT-Tag) platziert werden. Hierbei ist darauf zu achten, dass der JavaScript-Code vor dem LINK-Tag für eine externe CSS-Datei (wenn sich das nicht vermeiden lässt, siehe nächster Abschnitt) platziert wird. Andernfalls wartet der Browser mit der Ausführung des JavaScript-Codes so lange bis die externe CSS-Datei heruntergeladen wurde, was zu einer Verzögerung der Ladezeit führt.
Rendering blockierendes CSS entfernen
Jetzt geht es ans Eingemachte! Unterschiedliche Browser, Betriebssysteme und vor allem Bildschirmgrößen und -auflösungen haben einen anderen „above the fold“-Bereich, was bedeutet, dass es für einen privaten oder semi-professionellen Blog in vielen Fällen ein viel zu großer Aufwand wäre immer den passenden CSS-Code für genau den aktuellen Besucher im HTML-Dokument inline zu platzieren.
Nun bieten sich zwei praxistaugliche Alternativen an:
- Die „Mit dem Kopf durch die Wand“ – Methode: Einfach den kompletten CSS-Code inline im HEAD-Bereich des HTML-Dokuments platzieren.
- Die „Entdecker“ – Methode: Anhand von Tools den „above the fold“ Content für alle Unterseiten identifizieren und diesen direkt im HEAD-Bereich des Themes einfügen.
Die „Mit dem Kopf durch die Wand“ – Methode
Bei dieser Methode wird der gesamte CSS-Code inline im HTML-Dokument platziert. Dies kann manuell geschehen oder mithilfe des Plugins Autoptimize. Letzteres bietet hierzu in den Erweiterten Einstellungen die Option CSS Inlining aktivieren? an:
Messen Sie vor und nach der Aktivierung dieser Option unbedingt die Ladezeit Ihrer Seite anhand eines passenden Tools wie WebPagetest. Noch besser wäre die Messung der Ladezeit anhand eines RUM (Real User Monitoring) wie es beispielsweise Pingdom in der Gratisversion für eine URL anbietet. Der Grund hierfür: Durch das CSS-Inlining wird die HTML-Datei signifikant größer, was – auch ohne Berücksichtigung des Cachings – unter Umständen die Geschwindigkeit der Seite negativ beeinflussen kann. Im Folgenden wurde der Test External CSS vs. Inline CSS auf Blog IT-Solutions durchgeführt.
External CSS | Inline CSS | Veränderung | ||||||
---|---|---|---|---|---|---|---|---|
Zeit | StartRender | # | Zeit | StartRender | # | Zeit | StartRender | |
First View | 3.648s | 1.694s | 45 | 3.789s | 0.797s | 43 | +4 % | -53 % |
Repeat View | 1.112s | 0.618s | 7 | 1.133s | 0.502s | 7 | +2 % | -19 % |
Das Testergebnis zeigt eines klar: Wird der komplette CSS-Code in das HTML-Dokument eingebettet (Inline), dann hat das – zumindest im Firefox Browser, andere wurden nicht getestet – einen erheblichen Einfluss auf die StartRender Time, welche um über 50 Prozent reduziert werden konnte. Das heißt konkret, dass der Besucher nun bereits nach knapp 0,8 Sekunden die ersten Elemente im Browser angezeigt bekommt und nicht erst nach fast 1,7 Sekunden. Wie das im Speziellen aussieht zeigt der nachfolgende Vergleich:
Was in diesem Fall ein Problem ist und weshalb sich auch die Ladezeit etwas verschlechtert hat, ist die Größe der HTML-Datei mit dem Inline CSS-Code. Mit knapp 80 KB (im Vergleich zu 8 KB vorher) ist diese Datei einfach zu groß, woran natürlich der eingebettete CSS-Code schuld ist. Hier muss der Code generell etwas entrümpelt werden, indem unnötige Codezeilen entfernt werden. Dazu mehr im nächsten Artikel dieser Serie.
Neben der StartRender Zeit hat sich auch die Google PageSpeed Bewertung positiv entwickelt. Allerdings nur im mobilen Bereich, da im Desktop-Bereich noch eine JavaScript-Datei für das Nachladen einer alternativen Schriftart das Rendering blockiert.
External CSS | Inline CSS | |
---|---|---|
Google PageSpeed Mobil | 69 | 90 |
Google PageSpeed Desktop | 83 | 83 |
Die „Entdecker“ – Methode
Diese Methode ist schon wesentlich abenteuerlicher, vor allem deshalb, weil es aktuell noch keine leicht zu bedienenden Tools gibt, welche eine „above the fold“ CSS-Datei für alle Unterseiten einer speziellen Domain generieren. Abhilfe ist jedoch in Sicht, so teilte mir heute Frank Goossen, der Entwickler hinter Autoptimize mit, dass bereits erste Vorkehrungen für eine solche Funktion im Plugin getroffen sind und er daran arbeitet.
Bis dahin gibt die GitHub-Seite Above-the-fold CSS Tools eine Übersicht der bereits vorhandenen Tools, die nach Lust und Laune ausprobiert werden wollen. Das einfachste Tool davon ist der Critical Path CSS Generator, welcher für eine spezielle Seite – nachdem man manuell den CSS-Code reinkopiert hat – eine Critical Path CSS-Datei generiert.
Auf Blog IT-Solutions habe ich mich in diesem Fall erst einmal für die einfachere und schnellere “Mit dem Kopf durch die Wand” – Methode entschieden und werde darauf warten, bis geeignete Plugins das Inlining automatisieren.
Weiterführende Links
- Perfplanet.com – Why Inlining Everything Is NOT The Answer
- Ilya Grigorik – Optimizing the Critical Rendering Path for Instant Mobile Websites (Video)
- Frank Goossen – Should you inline or defer blocking CSS?
Fazit
Mit der Einführung der neuen PageSpeed Insights Bewertung hat Google einige Webseitenbetreiber in Aufruhr versetzt, die sich nun wieder etwas tiefer mit dem Thema der Platzierung von CSS- und JavaScript-Dateien beschäftigen. Die Antwort auf die Frage, was in Ihrem konkreten Fall nun die beste Lösung ist, ob JavaScript und CSS nun Inline oder doch lieber extern platziert werden sollen, muss ich Ihnen leider schuldig bleiben, denn das hängt von Ihrer Webseite sowie Ihren Besucherstatistiken ab.