CSS-Trick: CSS asynchron laden

CSS asynchron laden ist ein kleines Schmankerl für fortgeschrittene Web-Performance-Enthusiasten, die bereits alles auf ihrer Website optimiert haben. Wenn Du schon die Bilder skaliert und web-optimiert, den Code komprimiert, minifiziert und kombiniert, alles gecached und auf ein CDN verteilt hast, dann – erst dann! – ist asynchrones CSS Dein neuer Spielplatz. Alle anderen müssen erstmal ihre Hausaufgaben machen… ;-)

css-synchron-asynchron-opt2
image-155992

Basiswissen

Rendering ist das, was der Browser macht, wenn er eine Website darstellt. Dazu braucht es Zeit. Je schneller der Render-Przess durchlaufen wird, desto schneller ist die Website. Aus verschiedenen Gründen muss das Rendering manchmal unterbrochen bzw. geblockt werden. Dieses Blockieren vermindert die Performance der Website.

CSS und Javascript blockieren das HTML-Rendering einer Website. Wenn der Browser das HTML-Dokument abarbeitet und an die Stelle gelangt, wo JS oder CSS eingeführt wird, unterbricht er das Rendern und arbeitet erstmal das Scrtipt oder den Stylesheet ab. Wenn das abgeschlossen ist, geht es mit dem HTML-Rendering weiter. In diesem Zeitraum passiert nichts im Browser. Der User muss warten und sieht so lange (meistens) nur eine leere weiße Seite.

Während man bei JS sehr einfach die Blockaden vermindern kann, ist das mit CSS nicht so einfach. Wie man Rendering mit JS optimiert erkläre ich hier nicht. Dazu gibt es genug Infos im Netz.

Wie man das Rendering verbessert.

Mit den folgenden Methoden kann man die Blockaden im HTML-Rendering beeinflussen, welche durch CSS verursacht werden:

  1. Inline CSS
    Hier wird der Code direkt in das HTML-Dokument eingebettet. Das Rendering wird zwar geblockt, aber die Zeit für das Anfordern und Herunterladen einer externen CSS-Datei entfällt.
  2. Später Aufruf
    CSS wird im HTML-Dokument vor dem </body> gelegt. Auch hier wird das Render-Blocken nicht vermieden. Aber es wird so nach hinten verlagert, dass die Website schon mal angezeigt wird, wenn auch noch nicht richtig gestylt..
  3. Später Nachladen
    Die CSS-Datei wird mittels Javascript später in das Dokument eingefügt, wenn das Rendern der Seite abgeschlossen ist oder zumindest bis zu einem Punkt gelangt ist, wo die Seite schon verwendbar ist.
  4. Asynchrones Laden
    Die CSS-Datei wird parallel zum Code geladen und ausgeführt. Hier wird das Rendering nicht geblockt.

In diesem Artikel beschäftige ich mich vorwiegend mit dem asynchronen Laden von CSS. Zur Optimierung des Rendering müssen alle Methoden eingesetzt werden.

Warum das HTML-Rendering wegen CSS geblockt wird

Das Rendering wird für CSS unterbrochen, weil Scripte oft Informationen vom CSS brauchen. Würde ein solches Script vor dem CSS geladen, würde es diese Informationen nicht erhalten und Fehler produzieren. Darum muss CSS – zumindest das für Scripte potentiell relevante CSS – immer vor den Scripten geladen werden! Dieses CSS nennt man auch kritisches CSS.

Kritisches und unkritisches CSS

Was ist kritisches CSS? Kritisches CSS sind die Styles, die man für den sichtbaren Bereich einer Website benötigt = Above the fold. Das ist der sichtbare Bereich im Browser, wenn eine Seite geladen wurde und man noch nicht gescrollt hat.

Wenn man CSS asynchron laden will, muss man also wissen, dass man grundsätzlich nur unkritisches CSS verwenden sollte. Unkritisches CSS sind die Styles, die für den nicht sichtbaren Bereich einer Website benötigt werden = Below the fold.

Regeln

Die Regeln sind klar. Das wichtigste woran man denken muss:

  1. Below the fold kann man asynchron laden.
  2. Above the fold muss man inline oder als externe Datei im Head aufrufen.

Woher zum Teufel kriege ich dieses kritische und unkritische CSS?

Das ist die eigentliche Herausforderung. Es gibt verschiedene Tools und Methoden, wie man sein CSS zerteilen kann. Als Lektüre dazu möchte ich auf einen Beitrag bei CSS-Tricks verweisen: Authoring Critical Above-the-Fold CSS. Hier beschreibt Gastautor Ben Edwards den Stand der Dinge bei der Umsetzung.

Workflow Ansätze

Aus meiner Sicht gibt zwei Ansätze für den Workflow:

  1. Man verwendet PageSpeed Module auf dem Server und überlässt dem „Prioritize Critical CSS„-Filter die Arbeit. Das ist mit Sicherheit die bquemste Lösung.
    Allerdings hat das Modul einen pragmatischen Haken: Man benötigt Root-Rechte (sudo) für die Installation. Das ist leider bei meinen Kunden meistens nicht gegeben. Die meisten meiner Kunden betreiben Ihre Websites auf einfachen shared Webspaces. Sie haben keinen Root-Server. (Nicht mal ich habe das…)
  2. Integration eines CSS-Tools in die lokale Entwicklungs-Umgebung.
    Am praktikabelsten ist dabei für mich die Einbindung mit Grunt. z.B. Penthouse

Es gibt übrigens von Penthouse auch eine Online-Version. Aber damit kann man nur das kritische CSS einer Seite erstellen. Die obige Grunt-Version checkt dagegen die gesamte Website.

CSS asynchron laden

Von Scott Jehl gibt es ein sehr gutes Script, mit dem sich unrkitisches CSS sehr einfach einbinden lässt: loadCSS

LoadCSS macht dabei nichts anderes, als das die Medienabfrage (Media Query) zunächst auf einen unverfänglichen Wert zu setzen, der das Rendering nicht unterbricht – hier auf „nichts besonderes“:

[css]<link rel=“stylesheet“ href=“irgendwas.css“ media=“nichts besonderes“>[/css]

Wenn das Rendering durch ist, schaltet das Script den Wert um – hier auf „all“:

[css]<link rel=“stylesheet“ href=“irgendwas.css“ media=“all“>[/css]

Jetzt wird das Rendering wieder aufgenommen und das unkritsche CSS wird verwendet.

Für den Fall der Fälle, dass ein Browser mit JavaScript nicht klar kommt, sollte man als Fallback nicht vergessen, mit <noscript> das unkritische CSS-File nochmal vorzuhalten.

Schlussfolgerung

Die letzte Bastion des Rendering-Blockings ist endgültig gebrochen. Web-Performance-Optimierung wird damit noch komplexer und ich werde bei künftigen Projekten unkritisches CSS asynchron auslagern bzw. kritisches CSS inline einbauen.

Downloads

Lektüre

This entry was posted on by .

Heiko Mamerow

Buddhist, Vater, Freund, Internetseitenbauer, Sportler, Musikliebhaber & Verkehrsteilnehmer ;-)

7 Gedanken zu „CSS-Trick: CSS asynchron laden

  1. Thomas B.

    Hallo Heiko,

    ein sehr interessanter Beitrag auf den ich hier gestossen bin.

    Ich selber setze nicht WordPress ein sondern die Verhältnismäßig unbekannte Blogsoftware Dotclear.

    Leider gibt es für diese Blogsoftware keine fertigen Tools oder Plugins für die Optimierung der Ladezeiten, deswegen muss ich händisch eingreifen.
    Jetzt bin ich aber kein Programmier udn Style Experte, sondern mein Prinzip ist learning by doing.

    Ich hätte da noch einmal eine Frage?
    In diesem Script Aufruf kommt ja die Zeile „function loadCSS( href, before, media ){ … }“ vor.
    Ich denke mal das unter href irgendeine URL hinein muss, aber was für eine URL?
    Before und media denke ich mal muss nicht eingetragen werden.

    Oder verstehe ich das ganze komplett falsch?

    Über Tipps würde ich mich sehr freuen.

  2. Juri

    Hallo Heiko,

    ich beschäftige mich mitz dem ansynchronen Laden der css erst seit paar Tagen. Für mich ist es wichtig zu erfahren wie gut das ganze und vor allem wie groß der „Gewinn“ dabei ist. Wieviel CSS gehört zu dem kritischem CSS und was sind die Steuperfallen bei dieser vorgehensweise.

    Ich würde mich freuen zu lesen wie Deine Erfahrungswerte hierzu sind.

    Gruß, Juri

  3. Ibrahim der Integrierte

    Die Sache hat einen Haken und der Fuß hat einen Hacken, oder man nimmt Hacken um seinen Garten umzugraben. Alles klar? ;-) . Ansonsten, danke für den aufschlussreichen Artikel!

Kommentare sind geschlossen.