Neue CSS- und Javascript-Dateien sofort vom Server

Bei sich stetig entwickelnden Projekten ändern sich ebenso stetig auch die CSS- und Javascript-Dateien. Sie beinhalten neues Layout und Funktionen und sollen möglichst sofort zur Verfügung stehen.

Zugleich sollen diese Dateien aber möglichst lange (i.d.R. werden vier Wochen eingestellt) im Cache des Browsers liegen, um nicht bei jedem Seitenaufruf die teilweise über 100 Kb großen Dateien vom Server zu laden.

Ändern sich CSS- oder Javascript-Dateien, müssen sie jedoch sofort vom Server geladen werden und dürfen nicht mehr aus dem Browser-Cache kommen.

Es gibt drei Wege, das umzusetzen.

1. Dateien manuell umbenennen

Die umständlichste Methode in der Entwicklung, auch wenn eine IDE einem dabei gut helfen kann. Vorteil ist, dass sie ohne weitere Technik funktioniert, hat allerdings auch den Nachteil, leicht etwas übersehen zu können und die Versionsverwaltung mit überflüssigem zu füllen.

2. GET-Parameter

Beim Aufruf der CSS-/JS-Datei wird ein leerer GET-Parameter angehängt, der bei einem Update der Dateien zu setzen ist. Das kann z.B. das Datum sein:

<link href="css/style.css?20151001" rel="stylesheet" type="text/css" media="screen" title="style" />

Wird die Datei aktualisiert, ist ebenfalls der Parameter zu ändern:

<link href="css/style.css?20151024" rel="stylesheet" type="text/css" media="screen" title="style" />

Nachteil: Funktioniert nicht mit allen Browsern und nicht mit SSL/TLS.

3. ModRewrite und filemtime()

Diese Methode ist die sorgenfreieste, funktioniert auch mit TLS, erfordert allerdings bei jedem Request eine Serveraktion – was wiederum nur ein sehr kleiner Nachteil ist.

Die Idee ist, automatisch einen Namen mit einem Timestamp zu generieren, der durch ModRewrite auf die tatsächliche Datei umgelenkt wird. Dazu wird das folgende in die .htaccess eingetragen:

RewriteEngine on

# css and js versionizing, style.[timestamp].css|js
RewriteRule ^(.*)\.[\d]{10}\.(css|js)$ $1.$2 [L]

In PHP wird die Zeit der Datei ermittelt und zu einem neuen Namen zusammengestellt:

// get file time
$cssfile = 'style.css';
$mtime = filemtime($_SERVER['DOCUMENT_ROOT'].'/'.$cssfile);

// set timestamp before last extension
$cssfile = preg_replace('{\\.([^./]+)$}',".$mtime.\$1",$cssfile);

Das wird wiederum in HTML verwendet:

<link href="css/<?= $cssfile ?>" rel="stylesheet" type="text/css" media="screen" title="style" />

So können sorgenfrei jederzeit CSS- und Javscript-Dateien aktualisiert werden.

Die Idee ist nicht neu und wird seit langem auch auf stackoverflow diskutiert. Dort wird filemtime() auch in einer Funktion gekapselt, was aber auch nur selbstverständlich ist.

Hier noch die Zeilen für die .htaccess, um die statischen Dateien zu cachen:

<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType text/css "access plus 1 month"
ExpiresByType text/javascript "access plus 1 month"
ExpiresByType application/javascript "access plus 1 month"
ExpiresByType application/x-javascript "access plus 1 month"
ExpiresByType image/gif "access plus 1 year"
ExpiresByType image/jpg "access plus 1 year"
ExpiresByType image/jpeg "access plus 1 year"
ExpiresByType image/png "access plus 1 year"
ExpiresByType image/x-icon "access plus 1 year"
</IfModule>

Mit der 3. Methode lässt sich ein „access plus 1 year“ auch bei CSS und Javascript einstellen. Aber man muss es ja nicht übertreiben…

Schreibe einen Kommentar