Critical CSS
Von Bernhard Zeller am 07.12.2015
Angefangen hat alles mit Google PageSpeed Insights. Als Ben Edwards seine Website mit dem Tool von Google überprüfte, empfahl es ihm Teile von seinem CSS-Code inline im HTML-Dokument auszuliefern um die Ladezeit zu verkürzen. CSS Code in HTML einbinden, hört sich im ersten Moment schrecklich und falsch an. Gerade für mobile Geräte, wo die Internetverbindung nicht immer optimal ist (z. B. U-Bahn) ist eine Verbesserung der Ladezeit gewünscht. Da kann Critical CSS hilfreich sein.
Was Google PageSpeed aber damit sagen will ist, dass externe CSS-Dateien (eingebunden via `<link>`) das Rendern der Seite im Browser blockieren. Das heißt, dass das Rendern erst fortgesetzt wird, wenn die Dateien geladen sind. Was auch logisch ist, die Informationen müssen ja erst heruntergeladen werden, was durch Latenz und Dateigröße zu Verzögerungen führen kann. Die Empfehlung ist daher den CSS-Code aufzuteilen: Ein Teil inline, den Rest wie üblich in der CSS Datei.
Der Inline-Teil (also direkt im `<head>` durch `<style>`) soll alles beinhalten, was zum rendern des Sichtbereichs („above-the-fold“, der Begriff kommt von Zeitungen, wenn diese gefaltet sind, ist nur der obere Bereich der Zeitung sichtbar) notwendig is. Dieser Teil wird als „critical“ bezeichnet. Der Begriff „critical“ kommt von Ben Edwards, der diese Teile im CSS mit „critical“ angegeben hat.
Welcher Code ist kritisch?
Hört sich im Prinzip einfach an, aber wie kommt man jetzt an den Code der benötigt wird? Man könnte schon während der Erstellung darauf achten und diesen dann manuell kopieren. Das Ganze natürlich für die mobile und Desktop Ansicht ermittelt werden.
Es gibt dazu ein paar nützliche Tools:
- CriticalCSS.js: Code in die Browser-Konsole kopieren und mit URL ausführen.
- Critial Path CSS Generator: URL eingeben, CSS eingeben, generieren.
- Chrome Dev Tools Snippet (kann als Snippet in den Dev Tools angelegt werden): CriticalCSS Bookmarklet and Devtool Snippet.js
Wenn der kritische Teil des CSS eingebunden ist, kann auch noch zusätzlich der restliche Teil asynchron geladen werden, z. B. mit loadCSS.
Automatisierung
Schöner wäre es allerdings, das ganze zu automatisieren. Dazu kann man z. B. das Build System Gulp verwenden. Auf der Github-Seite von Addy Osmani gibt es dazu ein umfassendes Tutorial. Der Workflow mit Grunt wird im NPM Critical Package beschrieben.
Der Ablauf für den Task ist wie folgt:
- Stylesheet-Dateien vom Quellverzeichnis in das Build-Verzeichnis kopieren.
Notwendig für Fallback, falls kein JS aktiviert. - HTML-Datei einlesen und critical CSS ermitteln (dazu können Parameter wie Breite und Höhe angegeben werden).
Das wars auch schon. Vorher sollte man in der HTML-Datei die `<link>`-Tags mit den CSS-Dateien annotieren, die man zu einer Datei zusammenfassen will. Die kritischen CSS-Regeln werden automatisch eigebunden. Außerdem ein Script (loadCSS), das sich um das asynchrone Nachladen der CSS-Dateien kümmert.
Nachteil: Die CSS-Dateien werden nicht geändert, d. h. die Regeln werden doppelt ausgeliefert, da mit dem Package die kritischen Regeln so gut wie möglich zusammengefasst werden. Hier besteht sicher noch Optimierungsbedarf des Packages. Dies kann z. B. mit CSS-Preprozessoren umgangen werden, indem man seine Dateien aufteilt und sich selbst um den Above-the-Fold-Code kümmert (also wieder manuell).
Ich habe das auch mit Gulp und der MFG-Website getestet, was auch ohne Probleme funktioniert hat. Da die MFG-Website aber ohnehin recht schnell lädt, konnte ich keinen Unterschied feststellen. Was lange gedauert hat zu laden, waren die Schriften (Stichwort: „FOIT“).
gulp.task('critical', function() { critical.generateInline({ // Verzeichnis mit den Quelldateien base: 'src/', // HTML-Datei im Quellverzeichnis src: 'index.html', // Datei die das kritische CSS enthalten soll styleTarget: 'dist/critical.css', // Neue HTML-Datei mit kritischem CSS und "loadCSS" htmlTarget: 'dist/index.html', // Breite die abgesucht wird width: 320, // Höhe die abgesucht wird height: 480, // Minify minify: true }); });
Fazit
Auf kritisches CSS zu achten, ist zeitaufwendig, kann sich aber bezahlt machen. User sind schnell wieder weg, wenn sie das Gefühl haben, zu lange auf die Seite warten zu müssen. Und gerade bei mobilen Geräten verschafft es einen zusätzlichen Schub. Ob sich der Aufwand lohnt (vielleicht lässt sich die Seite auch in anderen Punkte optimieren? Vielleicht muss ich gar nicht so viele Ressourcen ausliefern?) muss jeder für sich entscheiden.
Wer HTTP/2 einsetzt, könnte auf solche Maßnahmen verzichten, denn damit lassen sich mehrere Requests mit einer Verbindung verarbeiten (Multiplexing) und Ressourcen können sich nicht mehr gegenseitig blockieren. Bis HTTP/2 aber allgegenwärtig ist dauert es sicher noch einige Jahre.
The comments are closed.