CSS Caching

Idealerweise sollte man das Caching selbst in die Hand nehmen, um die Kontrolle zu haben und es nicht einfach dem Browser überlassen. Es sollte aber auch immer die Möglichkeit geben einen Cache ungültig zu machen, sodass die Datei vor Ablauf des Caches neu geladen wird. Man stelle sich vor, das Caching für eine CSS-Datei ist auf einen Tag festgelegt, dann muss aber schnell ein Bugfix raus, jedoch bekommen die meisten User den Bugfix erst nach 24 Stunden mit, weil ihr Browser die CSS-Datei solange noch aus dem Cache lädt.

Cache einrichten

Um die Kontrolle zu übernehmen, arbeiten wir mit einer .htaccess-Datei, in der wir das Apache-Modul mod_expires verwenden. Der folgende Code aktiviert für alle Dateien vom Typ text/css ein Caching von 3 Tagen.

<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType text/css "access plus 3 days"
</IfModule>

Beim ersten Abruf des CSS bekommt der Browser den ETag der Datei mit und speichert sich diesen. Bei der nächsten Anfrage des Browsers sendet dieser also erstmal lediglich seinen lokal gespeicherten ETag an den Server, dieser vergleicht den empfangenen ETag mit dem der vorliegenden Datei. Weicht dieser ab, wird die Datei mit dem Statuscode 200/OK gesendet. Hat sich der ETag nicht geändert, sendet der Server nur den Statuscode 304/Not Modified zurück und der Browser greift auf die im Cache liegende Datei zurück.

Caching ohne Cache-Control

Das klingt etwas verwirrend. Hat man keine Möglichkeit das Caching mittels ETag zu steuern, ist man erstmal etwas hilflos. Der Browser entscheidet selbst, ob und wie lange er die Datei aus dem Cache liest, bevor er sie wieder erneut vom Server anfragt. Prinzipiell ist sowas nicht kritisch, doch gerade wenn man einen Bugfix online stellt, der möglichst schnell bei jedem User ankommen soll oder wenn ein neues Feature bereitgestellt wird, wo sich die Templates geändert haben und das alte CSS nicht mehr zu den neuen Templates passt, da würde man gerne forcieren, dass der Browser des Users die Datei neu lädt.

Nun, der Hash-Wert einer Datei ändert sich immer, wenn sich auch die Datei ändert – das können wir uns zu Nutze mache.

Statt:
<link rel="stylesheet" type="text/css" href="standard.css" />

Binden wir folgendes ein (am Beispiel mittels PHP):
<link rel="stylesheet" type="text/css" href="standard-<?php echo hash_file("md5", "standard.css"); ?>.css" />

Die Funktion hash_file() ist seit PHP 5.1.2 verfügbar. Was bewirkt das nun? Auf dem Server liegt nach wie vor nur die Datei standard.css, jedoch lassen wir den Browser glauben, dass wir z.B. die Datei
standard-bfa0b1fd14b9d8e0a6dcf4bd0ab623e1.css
einbinden. Der Hash-Wert einer Datei bleibt gleich, solange sich an der Datei nichts ändert. Jedoch wird nur eine Kleinigkeit am Inhalt der Datei geändert, so ändert sich auch automatisch der Hash-Wert. Die Hexadezimal-Zahl nach dem Bindestrich ändert sich also jedes Mal, wenn wir eine Änderung an standard.css vornehmen. Da der Browser glaubt, dass eine komplett andere Datei eingebunden wird, wird die Datei definitiv neu vom Server geladen.

So weit so gut, jedoch liegt ja auf dem Server aber immer nur die standard.css-Datei und keine Datei, die den langen Zahlencode im Dateinamen beinhaltet. Damit die Datei trotzdem gefunden wird bemühen wir das Apache-Modul mod_rewrite. Folgenden Code schreiben wir in die .htaccess-Datei:

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} ^(.*)-([a-f0-9]+)\.css$
RewriteRule ^(.*)-([a-z0-9]+)\.css$ $1.css

Die erste Zeile schaltet nur die RewriteEngine ein. In der zweiten Zeile wird die Bedingung definiert: Sie lautet, dass der Dateiname mit einer beliebigen Zeichenkette beginnt, dann folgt ein Bindestrich, anschließend eine Zeichenkette, die aus 0-9 und a-f besteht und zum Schluss endet der Dateiname auf .css. Die dritte Zeile ist nun die eigentliche Rewrite Regel: Der Teil des Dateinamens vor dem Bindestrich wird  genommen und serverintern wird eine Datei aufgerufen, die so lautet und auf .css endet.

Bei dieser Methode ist natürlich auch weiterhin direkt standard.css abrufbar, denn darauf passt die Rewrite-Bedingung nicht.

Veröffentlicht von

Hilko

2006 machte ich mein Hobby zum Beruf, startete mit einer Ausbildung zum Mediengestalter und arbeite inzwischen in Hannover als Frontend Web-Developer. Neben der Leidenschaft für semantisches Markup und den Möglichkeiten der aktuellen Frontend-Techniken, interessiere ich mich für das Reisen, fremde Kulturen und die Kunst der Fotografie.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.