Wenn das Brow­ser Caching einfach versagt

Von Zeit zu Zeit nutze ich GTMe­trix oder das von Goog­le ange­bo­te­ne Page­Speed Insights zur Leis­tungs­über­prü­fung der von mir betreu­ten Webpro­jek­te und um even­tu­el­le Opti­mie­rungs­be­dar­fe zu ermit­teln. Zuletzt nahm ich mir hier­für meine eige­ne Websei­te vor und bekam hier­bei von beiden Tools den Hinweis, ich möge doch für meine verwen­de­ten Schrift­ar­ten eine effi­zi­en­te­re Cache-Richt­li­nie bereitstellen.

GTMetrix moniert Browser Caching
GTMe­trix moniert das Brow­ser Caching meiner Fonts.

Grund­sätz­lich ist gegen diesen Ratschlag eigent­lich nichts einzu­wen­den: Zum einen handelt es sich bei den Schrift­art-Datei­en um verhält­nis­mä­ßig große Datei­en, selbst wenn diese – wie in meinem Fall – im moder­nen WOFF2-Format abge­legt sind. Und zum ande­ren sind es Datei­en, die nur selten einer Verän­de­rung unter­wor­fen, das heißt statisch sind. Also eigent­lich idea­le Kandi­da­te für ein (sehr) langes Brow­ser Caching.

Jedoch attes­tier­ten mir sowohl GTMe­trix als auch Page­Speed Insights für die betrof­fe­nen Ressour­cen eine nur recht kurze Lebens­zeit (Time to live, TTL): Für gera­de mal bis zu 30 Tage nach dem erst­ma­li­gen Aufruf war der Verbleib der Schrift­ar­ten im Cache des Brow­sers vorge­se­hen. Hier war der Hund begra­ben – denn eigent­lich war doch was ganz ande­res eingestellt.

Das Brow­ser Caching soll­te eigent­lich länger dauern

Gesteu­ert wird die Cache-Auslie­fe­rung über die Server-Konfi­gu­ra­ti­ons­da­tei .htac­cess, konkret in dem Modul­ab­schnitt mod_expires: Hier­in finden sich die von GTMe­trix bzw. Page­Speed Insights zitier­ten „Cache-Richt­li­ni­en“ – eine Aufrei­hung von Datei­ty­pen und korre­spon­die­ren­den TTL-Zeiten. Nach­ste­hend ein Auszug aus dem Modul­ab­schnitt meiner .htac­ces-Datei:

<IfModule mod_expires.c>
	ExpiresActive on
	ExpiresDefault                              "access plus 1 month"
	# Webfonts
	ExpiresByType font/ttf                      "access plus 4 months"
	ExpiresByType font/otf                      "access plus 4 months"
	ExpiresByType font/woff                     "access plus 4 months"
	ExpiresByType font/woff2                    "access plus 4 months"
</IfModule>

Die Anga­ben wurden zuvor von WP Rocket, einem Caching-Plug­in für Word­Press, gesetzt. Hier­bei ist deut­lich zu erken­nen, dass für Schrift­ar­ten im WOFF2-Datei­for­mat tatsäch­lich eine Gültig­keits­dau­er von vier Mona­ten nach Zugriff bestimmt wird. Wie kommt es also zu dieser Diskrepanz?

Was ist passiert?

Nach Durch­sicht des Trou­ble­shoo­ting Guides von WP Rocket und der darin empfoh­le­nen Prüfung, ob das Modul mod_expires auf dem Webser­ver über­haupt gela­den und akti­viert wurde (Antwort: Ja, wird es), folgt eine Prüfung des in der Expi­res­By­Ty­pe-Direk­ti­ve verwen­de­ten MIME-Typs (Ergeb­nis: korrekt). Warum also werden die Schrift­ar­ten nur mit einer Brow­ser Caching-Zeit von 30 Tagen ausgeliefert? 

Die Antwort ergibt sich, wenn man sich mod_expires als eine Kette von Wenn-Dann-Befeh­len vorstellt, also etwa wie folgt: „Wenn Dateityp=A, dann nimm Zeit Z1; wenn Dateityp=C, dann nimm Zeit Z2 und wenn Dateityp=unbekannt, dann nimm Zeit Z3.“

In meinem Fall wurde offen­sicht­lich der WOFF2-Datei­typ nicht als solcher erkannt, weshalb die entspre­chen­de Expi­res­By­Ty­pe-Direk­ti­ve auch ins Leere lief und statt­des­sen die Stan­dard-TTL von einem Monat verwen­det wurde (siehe hier­zu Expi­res­De­fault).

Eine außer­ge­wöhn­lich simp­le Lösung

Mit dieser Erkennt­nis liegt die Lösung im Grun­de auf der Hand: Wir müssen dem Webser­ver den korrek­ten Datei­typ beibrin­gen. Hier­zu hilft uns zum Glück ein weite­res Server-Modul inner­halb der .htac­cess, mod_mime. Hier können wir mittels AddTy­pe-Direk­ti­ve neue, bislang unbe­kann­te Datei­ty­pen hinzufügen:

<IfModule mod_mime.c>
	AddType font/woff2          woff2
</IfModule>

Diesen Code-Schnip­sel habe ich ganz am Anfang der .htac­cess-Datei plat­ziert. Dabei habe ich ganz bewusst darauf verzich­tet, nicht einfach den von WP Rocket selbst defi­nier­ten mod_­mi­me-Block zu modi­fi­zie­ren. Denn hier ist zu befürch­ten, dass dieser Bereich bei einer zukünf­ti­gen Aktua­li­sie­rung des Plug­ins wieder umge­schrie­ben wird. 

Und voilà: Nach der erfolg­rei­chen Aktua­li­sie­rung der .htac­cess und erneu­ter Durch­füh­rung der Leis­tungs­tests haben sowohl GTMe­trix als auch Page­Speed Insights grünes Licht gege­ben und das Brow­ser Caching als gut befun­den! Als Bonus hat sich durch diese Maßnah­me auch der von Goog­le errech­ne­te Punk­tes­core (wenn­gleich nur in einem gerin­gen Umfang, aber Klein­vieh macht bekann­ter­ma­ßen ja auch Mist) verbessert.

Zum guten Schluss

Im Nach­gang habe ich die Problem­stel­lung und die dazu­ge­hö­ri­ge Lösung an die Macher von WP Rocket weiter­ge­reicht, in der Hoff­nung, dass dies zum Anlass genom­men wird, entwe­der den Trou­ble­shoo­ting Guide um entspre­chen­de Hinwei­se zu ergän­zen oder – wenn möglich – die beschrie­be­ne AddTy­pe-Regel stan­dard­mä­ßig hinzuzufügen.

Es ist im Übri­gen nicht auszu­schlie­ßen, dass die glei­che Proble­ma­tik auch bei ande­ren Caching Plug­ins zum Vorschein kommt. Soll­te ich mich noch einmal damit befas­sen, werde ich es an dieser Stel­le publizieren.

Am Ende noch eine Warnung: Ände­run­gen an der .htac­cess bitte nur dann durch­füh­ren, wenn ihr euch wirk­lich eurer Sache sicher seid. Denn wie dieses Beispiel zum Brow­ser Caching zeigt, können hier einfa­che Dinge eine ganz große Wirkung entfalten!

Auch interessant