Im ersten Teil der Reihe „Webseiten beschleunigen“ hatte ich beschrieben, wie man mit Hilfe von OptiPNG die Dateigröße von Grafiken verkleinern und damit die Ladezeit verkürzen kann. Im zweiten Teil widme ich mich nun einem etwas komplexeren Thema, nämlich der Verwendung von Expires-Header.
Leverage browser caching
Wenn man mit dem Googletool PageSpeed die eigene Website analysieren lässt, dürfte bei den meisten wohl diese Meldung mit einem roten Ausrufezeichen angezeigt werden: Leverage browser caching. Dies bedeutet soviel wie, dass das Browsercaching nicht optimal eingestellt ist. Doch wie kann ich das Browsercaching meiner Seiten optimieren? Um dies zu erreichen, erkläre ich erst mal, wie so ein Browsercaching überhaupt funktioniert.
Funktionsweise des Browsercaches
Wenn man eine Website besucht, speichert der Browser des Users diese in einem Zwischenspeicher, dem Browsercache. Wenn der User die gleiche Seite ein zweites Mal besucht, fragt der Browser beim Webserver der Webseite nach, ob sich diese geändert hat. Falls ja, fordert der Browser des Users diese Seite nochmal neu an. Falls nein, liest der Browser diese aus seinem Cache. Das geht natürlich wesentlich schneller, da die benötigten Daten ja schon auf dem Rechner des Users liegen und nicht mehr per Internet übertragen werden müssen.
Im ersten Moment hört sich das nach einer optimalen Lösung an. Allerdings verbraucht auch bereits die Abfrage, ob die Seite schon mal besucht wurde oder nicht, eine gewisse Zeit. Für eine Datei ist das nicht viel, aber eine einzige Seite ruft ja oftmals 10-20 Dateien auf, wie z. B. das Logo, das Favicon, CSS-Dateien, Javascript-Dateien usw. Und bei jeder einzelnen Datei fragt der Browser beim Server nach, ob sich diese geändert hat. Diese vielen Abfragen summieren sich dann natürlich und allein dadurch kann sich die Ladezeit einer Seite um 2-3 Sekunden verlängern.
Den richtigen Zeitraum einstellen
Verhindern kann man dies, indem der Server dem Browser eines Users mitteilt, dass er für eine gewisse Zeit auf diese Abfragen verzichten soll. Dies erreicht man durch die Verwendung von Expires-Header. Mit einem Expires-Header gibt man an, für welchen Zeitraum diese Abfragen nicht mehr erfolgen sollen. Wie lange dieser Zeitraum ist, ist von Dateityp zu Dateityp verschieden und über die richtige Einstellung sollte man sich vor der Verwendung von Expires-Header einige Gedanken machen.
Der Nachteil, wenn man Expires-Header verwendet, ist nämlich, dass Änderungen, die man an einer Datei vornimmt, vom Browser des Users nicht erkannt werden. Schließlich fragt er ja nicht mehr nach, ob eine Datei geändert wurde oder nicht. Wenn man also z. B. eine wichtige css-Datei hat, sollte man den Zeitraum nicht zu hoch einstellen, weil der User die Änderungen an dieser Datei ja erst bei der nächsten Abfrage mitbekommt. Bei Bildern ist es dagegen meistens so, dass man diese nachdem man sie in die Website eingebaut hat, nicht mehr ändert. Deshalb kann man hier den Zeitraum ziemlich hoch einstellen.
Expires-Header verwenden
Nach dem langen theoretischen Vorgeplänkel, das aber leider notwendig war, folgt nun die Praxis. Wenn ihr Expires-Header verwenden wollt, müsst ihr folgende Eintragungen in eurer .htaccess machen.
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType text/css "access plus 1 week"
ExpiresByType application/javascript "access plus 1 month"
ExpiresByType application/x-javascript "access plus 1 month"
ExpiresByType image/gif "access plus 1 month"
ExpiresByType image/jpeg "access plus 1 month"
ExpiresByType image/png "access plus 1 month"
ExpiresByType image/x-icon "access plus 1 year"
</IfModule>
Die If-Abfrage in der ersten Zeile prüft ob das Apache-Modul mod_expires.c verfügbar ist. Falls ja, wird es aktiviert und der Zeitraum für die einzelnen Dateitypen wird eingestellt. ‚ExpiresByType text/css „access plus 1 week“‚ bedeutet z. B. dass nachdem der Browser des Users auf eine css-Datei zugegriffen hat, er eine Woche lang diese Datei aus dem Browsercache holt und sie erst nach Ablauf dieser Frist erneut einliest.
Man kann die Expires-Header natürlich auch noch für andere Dateitypen verwenden. Bei reinen HTML-Dateien macht es allerdings weniger Sinn, da diese ja meist nur wenige kb groß sind. Expires-Header lassen sich auch mit WordPress nutzen, allerdings sollte man die .htaccess nur ins Hauptverzeichnis bzw. in die Verzeichnisse wp-admin und wp-includes einbauen und nicht in das Verzeichnis wp-content.
Oben habe ich geschrieben, dass Änderungen an den Dateien erst nach Ablauf des eingestellten Zeitraums wirksam werden. Falls man trotzdem wichtige Änderungen vornehmen will, die sofort bei allen Usern sichtbar werden sollen, kann man zu einem kleinen Kniff greifen. Man hängt an die Datei, die man ändern möchte, einfach eine Zahl an, z. B. style2.css und ändert den Aufruf im HTML-Code. Da diese Datei für den Browser ja neu ist, wird er sie neu einlesen. Dieser Trick ist aber nur bei kleinen Websites sinnvoll oder wenn nur wenige Dateien geändert werden müssen, da der Aufwand sonst zu groß wird.
Was bringen Expires-Header?
Ich habe den oben geposteten Code in die .htaccess meiner Rätselseite eingebaut und ich war überrascht über die erhebliche Leistungssteigerung, die der Einsatz der Expires-Header gebracht hat. Ich hatte das Gefühl, als hätte ich einen kleinen Turbo dazugeschaltet 🙂
Und das Schöne daran ist, man schlägt 2 Fliegen mit einer Klappe. Erstens verringert sich die Ladezeit beim Besucher der Website und zweitens wird auch der Server weniger beansprucht, da er ja weniger Anfragen bearbeiten muss.
Eigene Erfahrungen mit Expires-Header
Setzt ihr auf euren Websites auch Expires-Header ein? Welche Zeiträume habt ihr für die einzelnen Dateien eingestellt? Schreibt doch in den Kommentaren was zu euren Erfahrungen.
Artikelreihe Webseiten beschleunigen:
Teil 1: Dateigröße von Grafiken verkleinern
Teil 3: Parallele Downloads
Teil 4: Die gzip-Compression
Teil 5: Code optimieren
Gilt die Expiration serverseitig oder userseitig? Wird das über einen Cookie geregelt?
Die Expires-Header gelten userseitig. Was übrigens auch den Nachteil hat, dass man keinen Einfluss darauf hat, was der User macht. Wenn er seinen Cache leert, werden alle Daten nochmal neu angefordert.
Die Einstellungen werden nicht in einem Cookie gespeichert, sondern in einem HTTP-Header übertragen und im Browsercache gespeichert. Das kannst du sehr schön sehen, wenn du Firefox benutzt. Gib dort mal in die Adresszeile „about:cache“ ein und klicke bei „Disk cache device“ auf „List Cache Entries“. Dort siehst du alle Cacheeinträge und bei Expires siehst du das Ablaufdatum.
Ja, auch wir nutzen dies, denn es schont CPU und Bandbreite.
Daneben setzen wir auf Komprimierung(Content-Encoding: gzip), wo aber die CPU etwas leidet. Dafür spart man beim HTML-Code bis zu ca. 85% Bytes auf der Leitung.
>> allerdings sollte man die .htaccess nur in die Verzeichnisse wp-admin und wp-includes einbauen und nicht in das Verzeichnis wp-content. <<
Die .htaccess gehört doch in das Root-Verzeichnis von WordPress. So hab ich das jedenfalls bei allen Installationen.
@Matthias Ja, hast recht. Das war missverständlich formuliert. Ich habe es mal korrigiert. Danke für den Hinweis 🙂
Ich kann das nur bestätigen. Ich arbeite hauptsächlich mit TYPO3 und WordPress, und vor allem TYPO3 ist ja ziemlich ressourcenhungrig.
Seitdem ich konsequent Expires Header und gzip-Komprimierung einsetze, rennen auch die TYPO3-Seiten regelrecht, sind fast so schnell wie statische HTML-Seiten.
Kann man das auch für einen XT-Commerce Shop benutzen ?
Ich kenne mich mit XT-Commerce nicht aus, aber ich wüsste nichts, was gegen die Verwendung von Expires Header sprechen würde.
Hallo, danke für die schnelle Antwort. Ich hätte noch ne Frage und zwar kommt bei mir folgendes raus wenn ich eine Header Abfrage mache:
•HTTP/1.1 200 OK
•Date: Tue, 29 Mar 2011 13:13:31 GMT
•Server: Apache/1.3.39 (Unix) PHP/4.4.7
•X-Powered-By: PHP/4.4.7
•Set-Cookie: XTCsid=eabe35753aae39cdbad148aea18c9326; path=/
•Expires: Thu, 19 Nov 1981 08:52:00 GMT
•Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
•Pragma: no-cache
•Content-Type: text/html
Die Header Abfrage habe ich hier gemacht >>> http://www.internalscripts.de/werkzeuge/http-header-abfrage.php
Meine Frage bezieht sich auf Expires und Cache-Control ist das so richtig ? Wobei bei Expires irgendwas ja nicht stimmen kann laut diesem Datum oder ?
Hab das grad durch den Link im XHTML-Forum gefunden und gleich mal in meine HTACCESS übernommen. Den Geschwindigkeitsgewinn sieht man direkt. Und damit ist deine Seite auch gleich mal gebookmarkt 😉
Hallo nochmal ich,
also ich habe die Eintragung in der .htaccess vorgenommen, allerdings bin ich mir jetzt nicht sicher. Folgendes, ich muß doch die Daten meiner Seite anpassen oder ?
Ich benutze einen XT Shop und so wie ich es gelesen habe sind diese daten doch für wordpress oder ?
Wenn ja dann muß ich doch z.B. für
ExpiresByType text/css „access plus 1 week“
ExpiresByType application/javascript „access plus 1 month“
andere Daten angeben, da so wie diese hier stehen nicht bei mir vorhanden sind, sondern in einem anderen Ordner sind.
Genauso ist es mit
ExpiresByType application/x-javascript „access plus 1 month“
dieses habe ich garnicht bei mir drauf. Kann das alles sein ? Wäre dankbar für eine Antwort.
@DVD Diese Befehle sind unabhängig von dem verwendeten Skript. Sie funktionieren also bei WordPress genauso wie bei XT Commerce, einem Forum oder einer ohne Skript erstellten Website.
Mit dem Befehl
ExpiresByType text/css “access plus 1 week”
weist du den Browser an, alle CSS-Dateien (dafür steht die Angabe „text/css“) 1 Woche lang aus dem Browsercache zu holen und nicht erneut von der Webseite zu laden.
Die erste Angabe hinter ExpiresByType ist also immer der Dateityp, die zweite Angabe ist die Dauer wie lange der Befehl wirkt.
Um herauszufinden, warum der Expires-Wert im Header falsch gesetzt ist, müsste ich wissen, welche Befehle du in deiner .htaccess stehen hast.
Du kannst mir die Befehle auch gerne bei E-Mail schicken, dann gucke ich mir sie mal an.
Ich habe eine email gesendet.
Danke, genau die Information habe ich gerade gesucht, nachdem ich diesen google-Test gemacht habe, wo mir das als wichtigste Änderung angezeigt wurde, die ich vornehmen sollte.
Werde mich nachher mal daran machen und das umsetzen, ich hoffe, dass ich es hin bekomme.
Kann man den „expire“ befehl auch für .php seiten nutzen? Und wird als Zeitangabe auch „plus 3 weeks“ akzeptiert?
Danke für den Super Tipp!
Ich wollte das Modul mal mit XAMP ausprobieren, aber irgendwie klappt es nicht.
Laut Browser, wird zwar der Header „Expires….“ übertragen, aber bei einem Reload wird trotzdem eine neue Anfrage ausgeführt.
(Habe in einem CSS Sheet etwas geändert und die Änderungen waren nach dem Reload sichtbar)
Wieso?
btw: Lt. http://httpd.apache.org/docs/2.0/mod/mod_expires.html
werden für die „“ Zeitangaben im Plural verwendet.
Also auch bei einer Woche: „1 weeks“.
@Chris Da kann ich dir leider nicht weiterhelfen, weil ich es mit XAMPP nicht ausprobiert habe.
“week” müsste auch funktionieren:
http://page-speed.net/tipps/leverage-browser-caching.html
Inzwischen scheint es doch zu funktionieren. Warum weiß ich nicht. Nach einem zweiten und Browser- und Serverneustart…
Ok, kann sein, dass „week“ auch funktioniert. Mir fiel es nur in der Doku auf, dass dort nur der Plural verwendet wurde.
Danke & LG
Gibt es für das Problem von DVD im XT-Commerce bereits eine Lösung ? Habe das gleiche Problem mit dem Expires: Thu, 19 Nov 1981 08:52:00 GMT …
Funktioniert bei mir nicht… keine Ahnung warum aber Pagespeed sagt trotz aktivierter Funktion es wird nichts geaachded.
hallo ich hab mal eine frage..
gibt es auch einen befehl für die css images?
die bekommen bei mir keinen expired.
page speed bemängelt alle bilder aus der css mit „Ablauf nicht festgelegt“
muss es nicht ExpiresByType image/jpg „access plus 1 month“ (**** JPG NICHT JPEG ****) heissen?
ich weiss das es auch .jpeg endungen gibt.. aber 99% der bilder sind doch .jpg
Hallo,
ich suche freiberufliche Unterstützung zu dem Thema, da ich es alleine nicht hinbekomme. Wer Interesse hat das für mich im Stilmagazin zu erledigen (WordPress + VBulletin Installation) bitte unter info@stilmagazin.com melden, vielen Dank!
Andreas
Hallo,
super Beitrag, leider bekomme ich nach der Eintragung einen Fehler 500.
Ich habe mir die PHPinfo Ausgabe angeschaut und das Modul scheint geladen zu sein.
Unter Loaded Module: mod_expires
Hat vielleicht jemand einen Tipp für mich, was ich falsch mache?
Gruß
Frank
@Frank Hast du nach der Änderung den Browsercache gelöscht? Einfach mal STRG + F5 drücken.
Hallo,
ja habe ich. Ich habe mir auch gerade mal die Logfiles angeschaut. Interessanterweise bekomme ich eine Fehlermeldung wie folgt:
ExpiresActive not allowed here
Und ich bin schon einige Anleitungen durch gegangen…
Jetzt gerade gucke ich in die httpd.conf, aber auch da wird scheinbar alles erlaubt.
Gruß
Frank
Hallo,
> Expires: Thu, 19 Nov 1981 08:52:00 GMT
Die Seite ist seit über dreißig Jahren abgelaufen und wird nicht mehr gecached.
Damit dürfte das letzte Rätsel gelöst sein 😉
Super, habe es eingebaut und es funktioniert. PageSpeed Insights von Google bestätigt mir mehr Geschwindigkeit.
Vielen Dank für die super Information.
Gruß
Rainer
Hi, gibt es auch eine Möglichkeit ein Abaufdatum für eine entfernte Resource zu setzen? zb für http://www.google-analytics.com/analytics.js
Hey Cujo,
Ich hab Deinen Tip grad auf der Seite meiner Fun-Gothic Band Silberschauer eingesetzt und sofort einige Punkte mehr im PageSpeed von Google bekommen. Ich muss mir mal die Specs in Ruhe durchlesen, um herauszufinden, wie man das am besten für einzelne Skripte und Sheets macht; ich dachte bisher immer, daß die Browser cachen, wär die Standarteinstellung.
Viele Grüße,
.rhavin