registrieren registriertes Mitglied


Anzeige

Anzeige

HowTo: Wie lagert man Critical CSS aus?

Stell hier Deine Frage zu: HTML, CSS, PHP, MySQL, htaccess, robots.txt, Javascript usw
supervisior
PostRank 10
PostRank 10
Beiträge: 3389
Registriert: 26.06.2006, 09:11

Beitrag supervisior » 09.03.2021, 11:11 HowTo: Wie lagert man Critical CSS aus?

Vor dem Hintergrund, dass sich durch die Core Web Vitals jetzt immer mehr dafür interessieren, wie man seine Seite bestmöglich optimiert, um den Pagespeed Gott zu besänftigen, hier mal 1 von mehreren Wegen, wie man das Problem mit dem Critical CSS lösen kann. Wobei lösen genau genommen nicht stimmt, weil die eigentliche Ursache auch durch die nachfolgende Lösung bestehen bleibt. Pagespeed regt sich aber nicht mehr drüber auf und man erzielt damit auch eine Verbesserung, sowohl beim Score als auch beim Ladeverhalten.

Ob diese Lösung funktioniert, bzw. das Erhoffte einbringt, kann nicht gänzlich garantiert werden, weil es im Einzelnen dann doch von jeder Seite abhängt. Eine denkbare ungünstige Situation besteht, wenn man z.B. als Wordpress Nutzer, aber auch alle anderen Applikationen auf externe Dienste setzt. Gemeint ist damit Google Analytics, Adsense, alle Social Media Plattformen, aber auch Dienste von Bewertungsseiten, wie Trusted Shops und andere.

Warum ist das ungünstig? Eigentlich ganz einfach zu verstehen. Wenn man solche Dienste nutzt, dann wird mit jedem Seitenaufruf oftmals mehr als 1 Request an den Server des jeweiligen Anbieters vorgenommen und zumeist Javascript nachgeladen. Nicht, dass Javascript schlecht wäre, aber das Javascript muss auch vom Browser verarbeitet werden und dieses Verarbeiten blockiert nicht selten das Laden der Sourcen vom eigenen Server und ebenso das Verarbeiten dieser Sourcen. Der Browser hat also viel zu tun und alles, was ihn beim Abarbeiten stört, beeinflusst die Anzeige im Browser und folglich wirkt es sich auf die Web Vitals aus. Der Idealzustand wäre, wenn man gänzlich auf solche Dienste verzichten würde und das nicht nur wegen dem Critical CSS.

Geht es nun konkret um Critical CSS muss man zunächst Klarheit schaffen, was Critical CSS überhaupt ist. Ich wills mal so sagen, hätte man diese Begrifflichkeit in Deutschland erfunden, hätte man das sicherlich nicht Kritisches CSS genannt und ist vom Urheber meiner Meinung nach etwas unglücklich gewählt, weil es eigentlich nicht um kritisches CSS geht, sondern um einen kritischen Bereich und das CSS, das man für diesen Bereich benötigt.

Mit dem kritischen Bereich gemeint, ist der sog. Bereich "above the fold", was man im Deutschen so auch nicht kennt, aber ursprünglich aus den Print Medien stammt. Im Speziellen bei Zeitungen und Zeitungen sind zumeist zusammengefaltet, so dass es einen Bereich über der Knickfalte gibt und einen darunter. Der Bereich über der Knickfalte, also "above the fold", ist der besagte kritsche Bereich, den u.a. auch die Web Vitals priorisieren. Es geht also darum alles erdenkliche zu unternehmen, dass genau dieser Bereich as soon as possible im Browser angezeigt wird. Alles danach und darunter kann warten und lädt man vorzugsweise verzögert, wie z.B. Bilder oder andere Sourcen, die man für den kritischen Bereich nicht sofort benötigt.

Wenn nun Pagespeed meint man solle kritisches CSS auslagern, dann ist das so verstehen, dass man das benötigte CSS für den kritischen Bereich priorisiert und alles andere CSS, dass man für den kritischen Bereich nicht benötigt "auslagert", wenngleich auslagern eigentlich meint, dass man es verzögert laden soll damit die Anzeige im kritischen Bereich dadurch nicht beeinträchtigt wird. Der Haken an der Sache ist nur, dass sich das im Praktischen so gut wie gar nicht umsetzen lässt, weil der kritische Bereich relativ ist und vom Gerät, bzw. Auflösung, bzw. Anzeigegröße abhängt. Ein Verkleinern des Browser Fensters genügt schon, um einen gänzlich anderen kritischen Bereich zu haben. Gleichermaßen verhält es sich, wenn man sein Smartphone von der vertikalen ins horizontale dreht. Da fragt man sich natürlich, was soll der Sch***, wenn sich das nicht realisieren lässt?

Die Lösung dieses Dilemmas besteht darin, dass man erst gar keine Zeit damit verschwendet, wie man das technisch lösen könnte. Die Ursache dafür liegt nämlich ganz woanders. Wenn Pagespeed meint man solle Critical CSS auslagern, dann ist das ein fast unmittelbares Indiz dafür, das es einfach zu viel CSS gibt. CSS ist ja nicht nur eine einfache Textdatei, sondern enthält Formatierungsangaben, die der Browser verarbeiten muss und gehört zu den Elementen, die dem Browser am meisten abverlangt. Wenn dann das verwendete Gerät nur Schwach auf der Brust ist, wird übermäßiges CSS zum Killer. Das Problem mit dem zu viel an CSS ergibt sich sehr oft bei responsiven Templates/Themes. Diese bekommt man zwar nicht selten for free, aber man bezahlt dann doch durch schlechte Ladezeiten, bzw. einen schlechten Score. Ohne das jetzt unnötig zu vertiefen, sollte man bei der Anschaffung eines Templates/Themes darauf achten, dass man es vorher nicht nur Live sehen kann, sondern man auch mal Pagespeed zeigt. Von der Optik allein also bitte nicht täuschen lassen! Es zählen bekanntlich auch die inneren Werte! :)

Hat man nun so ein Template/Theme und Pagespeed moniert das mit dem Critical CSS, aber man selbst nicht in der Lage ist an dem zu vielen CSS etwas zu ändern, könnten die diversen Plugins allen voran für WP weiterhelfen, zumindest besteht damit zumeist die Möglichkeit ggf. mehrere CSS Dateien zu 1 CSS Datei zu bündeln. Das ist nicht die unmittelbare Lösung, hilft für die eigentliche Lösung aber sehr stark weiter.

CSS wird in der Reihenfolge aller zu ladender Sourcen in der Regel gleich als erstes geladen. Alle anderen Sourcen, die sich beim Laden der Sourcen vordrängeln stören das Abarbeiten von CSS und weil CSS maßgeblich die Anzeige und die Geschwindigkeit der Anzeige beeinflusst, ist es nach Maßgabe der Web Vitals wichtig, dass man das Laden und das Verarbeiten von CSS priorisiert und das ganz besonders für den besagten kritischen Bereich above the fold und das vor allen anderen Sourcen. Das vorrangige Laden von CSS vor allen anderen Sourcen genügt aber zumeist nicht und besonders dann nicht, wenn es zu viel CSS gibt. Meine persönliche Schmerzgrenze liegt bei 150kb, was nach wenig klingt und auch ist, aber man braucht nicht mehr. Alles darüber hinaus ist unnötiger Ballast. Wie es nicht wenige WP Theme (Er)Bauer schaffen für ein popeliges WP Theme bis zu 1 MB zu produzieren, ist mir ein Rätsel.

Ziel der angekündigten Lösung ist nun, die ohnehin schon vorhandende Priorisierung noch weiter zu steigern. Dafür hält das HTTP Protokoll (nicht HTTP/1.x) und HTML Werkzeug bereit, das in allermeisten Fällen aber nicht genutzt wird, obgleich man mit geringem Aufwand sehr viel erreichen kann. Egal ob per HTTP oder HTML geht es bei beiden Werkzeugen um das Vorladen von Sourcen, insbesondere von CSS, noch bevor es durch die Definition im Quellcode vom Browser angefragt wird. Durch das Vorladen soll erreicht werden, dass der Browser die Source schon im Cache hat, sodass er es nicht erst laden und dann erst Verarbeiten kann. Hat er es im bereits Cache, geht das Verarbeiten folglich umso schneller. So die Idee.

Das mit dem Vorladen funktioniert auch wunderbar, allerdings gibt es Unterschiede auf welche Art man das Vorladen macht. Dementsprechend unterschiedlich ist auch das Ergebnis. HTML hält dafür den preload HTML Tag bereit. Das damit erreichte Vorladen hat den Vorteil, das es unabhängig vom verwendeten HTTP Protokoll und Webserver funktioniert. Hat allerdings den Nachteil, dass der Preload Aufruf eigentlich zu spät erfolgt, weil er wie der normale CSS Aufruf im HTML Header erfolgt. Das bedeutet aber nicht, dass diese Art preload nichts bringen würde, aber je größer die Source ist, die vorgeladen werden soll, umso geringer ist die Wahrscheinlichkeit, dass durch das Vorladen der gewünschte Effekt erreicht wird. Ich persönlich bin kein Freund davon. Nicht nur aus den vorher genannten Gründen, sondern besonders, weil es sich für die meisten in Ermangelung von HTML Kenntnissen nicht umsetzen lässt. Zumal auch viele der Optimierungs-Plugins es nicht unterstützen, bzw. nicht anbieten. Wenn doch, dann sollte man es aber nutzen, wenngleich diese Art Vorladen auch einen nicht unerheblichen Nachteil hat, der sich zwar lösen ließe, aber man dafür PHP Kenntnisse benötigt.

Was es mit diesem Nachteil auf sich hat, versteht man, wenn man ebenso versteht, was man vorladen kann. Dazu zählen in erster Linie statische Sourcen, also Fonts, CSS, Javascript und Bilder. Alle diese Sourcen haben die Eigenschaft, dass diese nach dem erstmaligen Laden im Browser Cache gespeichert werden. Ein mehrmaliges Vorladen von Sourcen, die sich bereits im Browser Cache befinden, ist also Quatsch und Ressourcen Verschwendung und genau das ist das Problem bei dem Vorladen per HTML preload Tag. Kann zwar auf einfachste Weise per PHP gelöst werden, aber das kann halt nicht jeder. Somit ist diese Art Vorladen nicht massentauglich und vergessen es schnell wieder.....

Die viel bessere Lösung für das Vorladen ist der sog. Server/PUSH, eine seit Verfügbarkeit des HTTP/2 Protokolls existierende Vorladefunktion, die in der Regel bei jedem Webserver aktiv und somit nutzbar ist, wenn der Provider diese Funktion nicht deaktiviert hat. Der entscheidende Vorteil der PUSH Funktion besteht darin, dass er als Header bereits an den Webserver gesendet wird noch bevor 1 Byte des HTML Body, also dem eigentlichen Quelltext, gesendet wird. Damit wird also genau die Priorisierung erreicht, die man haben will. Außerdem lässt sich das mehrfache Vorladen bedingt einfacher lösen als mit dem HTML Tag. Server/Push wird von allen gängigen Browsern, aber leider mit Ausnahme des Safari Browser auf dem Mac, unterstützt.

Einen Header kann man unabhängig der Funktion per PHP senden, aber auch mittels .htaccess. Nachdem es für PHP aber einmal mehr PHP Kenntnisse bedarf, konzentrieren wir uns für eine massentaugliche Lösung auf die .htaccess Variante, die deutlich einfacher zu bewerkstelligen ist. Wenngleich diese eigentlich von fast jedem umsetzbar sein sollte, hat diese einen bedingten Nachteil. Damit das mit dem Vorladen funktioniert, ist es unabdingbar, dass die URL der vorzuladenden Source genau der URL entspricht, die auch im HTML Header dfiniert ist. Nicht selten werden besonders an CSS und Javascript Dateien Zeitstempel oder ein Hash in Form eines GET Parameters angehängt. Ändert sich dieser Hash und passt man diesen Hash nicht auch in der URL der vorzuladenden Source an, wird diese Source zwar auch vorgeladen. Allerdings erwartet der Browser die URL, die per CSS definiert ist. Der Browser kann mit der falschen Vorladung also nichts anfangen und man lädt etwas vollkommen unnützes. Darin liegt der Vorteil der PHP Variante bei der sich dieser Hash dynamisch anpassen lässt und man nicht jedesmal manuell etwas ändern muss, wenn sich der Hash verändert hat. Um es aber trotzdem massentauglich zu machen, bleiben wir aber bei der .htaccess Variante.

Noch bevor jetzt die eigentliche Lösung präsentiert wird, noch etwas, was es zu beachten gilt. Vorladen bringt viel und kann auch das mit dem Critical CSS lösen, allerdings sollte und darf man es nicht übertreiben. Wer jetzt glaubt er hätte einen Vorteil, dass er alle Bilder auf einer Seite vorladen müsste, erreicht damit genau das Gegenteil. Deswegen ist es wichtig nur das vorzuladen, was es besonders für den kritischen Bereich braucht und eben nicht mehr. Dazu gehören Fonts als erstes und danach CSS. Nach Möglichkeit nur 1 davon und sofern im Kopf der Datei vorhanden 1 Bild. Javascript geht auch, sollte man allerdings abwägen und davon abhängig machen wie groß die Dateien für Fonts, CSS ist. Im Zweifelsfalle erst mal weglassen.

Die Datenmenge spielt insofern eine wichtige Rolle, weil besonders der Firefox sensibel darauf reagiert. Ist z.B. die CSS Datei größer als 150kb und gibt es sonst noch 10 Pfund an vorzuladenden Sourcen, überspringt der Firefox die vorzuladenden Sourcen. Deshalb mit Gefühl an die Sache herangehen. Dem Chrome Browser macht die Datenmenge nach meinen Beobachtungen am wenigsten bis gar nichts aus. Dazu zählen auch alle Browser, welche die Chromium Engine verwenden.

So, jetzt aber endlich zur angekündigten Lösung, die man einfach per Copy & Paste idealerweise ganz weit oben in die .htaccess reinkopiert. Wichtig natürlich, dass man vorher den Pfad und die Datei Namen ändert.

Code: Alles auswählen

SetEnvIf Cookie "smartpush=1" h2push
Header add Link "</path_to_font/font.woff2>;rel=preload;as=font;crossorigin=anonymous,</path_to_css/stylesheet.css>;rel=preload;as=style,</path_to_image/image.jpg>;rel=preload;as=image" env=!h2push
Header add Set-Cookie "smartpush=1; Path=/; Secure; HttpOnly" env=!h2push
Der obige Code lädt nun also die jeweilige Source vor, allerdings nur dann wenn der Cookie "smartpush" noch nicht gesetzt wurde. Gibt es diesen noch nicht, wird dieser gesetzt. Der Cookie hat nur eine Lebensdauer solange wie die Besuchersitzung dauert. Schließt man den Browser, ist dieser inaktiv, bzw. wird vom Browser automatisch gelöscht.

Die Parameter sind je nach Source unterschiedlich und müssen entsprechend so definiert werden.

Fonts = </path_to_font/font.woff2>;rel=preload;as=font;crossorigin=anonymous
CSS = </path_to_css/stylesheet.css>;rel=preload;as=style
Image = </path_to_image/stylesheet.css>;rel=preload;as=style
Javascript= </path_to_image/javascript.js>;rel=preload;as=script


Wer sich jetzt noch tiefer in die Materie Server PUSH eingraben will, es gibt eine Unmenge an Quellen darüber. Den Kritikern sei in weiser Voraussicht gesagt, dass die Diskussion über PUSH bereits an anderer Stelle hinreichend ausdiskutiert wurde und jetzt nicht nochmal aufgewärmt werden muss, zumal das Jetzt zählt und nicht, was vielleicht kommen könnte. Die Vorteile von PUSH stehen über allem.

Enjoy! ;)

[Nachtrag]

Das mit dem Preloaden kann man auch als Breitbandantibiotikum verstehen und wirkt deswegen nicht nur für Critical CSS. Zumindest bei Pagespeed lässt sich beobachten, dass dort die einzelnen Vitals in Wechselwirkung mit anderen stehen. Wenn man einen der Vitals also ändert bzw. verbessert, geschieht es sehr oft, dass sich daduch auch andere ändern. So in etwa wirkt sich das auch beim Preloaden aus. Die Wahrscheinlichkeit ist also groß, dass sich durch das Vorladen auch die anderen Vitals mit verbessern.

Anzeige von: