Mit Expires-Header die Performance von Websites verbessern - Teil 1

Mit Expires-Header die Performance von Websites verbessernExpires-Header - Nimmt man sich vor, die Ladezeiten einer Website zu verbessern, sind einige Maßnahmen recht schnell umgesetzt. Es gibt Tools, die das Kombinieren und Minimieren von CSS und JavaScript ermöglichen. Das Komprimieren textueller Ressourcen übernimmt eine simple Apache-Konfiguration. Stylesheets im Head des Dokuments zu platzieren, stellt auch keine große Hürde dar. Die Konfiguration eines Far Future Expires-Header wird von den meisten Entwicklern jedoch ausgelassen. Dieser Performance-Kandidat mit dem seltsamen Namen (und der noch seltsameren Übersetzung) soll in einer 3-teiligen Artikelserie etwas ausgiebiger vorgestellt werden.

Wissenswerte Hintergründe

Expires-Header sind für Ressourcen interessant, welche sich bereits im Cache des Browsers befinden und vom Browser aus diesem bezogen werden (man spricht vom sogenannten Primed Cache). Das ist immer dann der Fall, wenn sich mehrere Seiten die selben Ressourcen teilen oder wenn Nutzer die Website erneut besuchen (in Statistiken unter wiederkehrende Besucher zu finden). In einem solchen Fall bevorzugt der Browser die gecachte Version der Ressource und lädt diese nicht erneut vom Server.

Dem Browser wird durch diesen Header ein "Verfallsdatum" genannt. Bis zum Ablauf dieses Datums bezieht dieser die Ressource dann aus dem Cache, ohne nochmals mit dem Server zu kommunizieren.

Um jedoch sicher zu gehen, dass sich die Ressource seit dem Download vom Server nicht verändert hat, werden vom Browser mittels eines Conditional GET Requests verschiedene Daten mit dem Server abgeglichen. Anhand des Last-Modified-Headers oder eines ETag kann der Server feststellen, ob sich die Ressource verändert hat und ob er sie erneut an den Browser senden muss. Wird keine Veränderung festgestellt (und das sehr hüufig der Fall), ist diese Kommunikation zwischen Client und Server an sich überflüssig und führt zu einer unnötigen Verzögerung.

Ein praktisches Beispiel

Mit Hilfe von webpagetest.org kann dies sehr einfach für die eigene Seite überprüft werden. Der Service protokolliert den gesamten Datenverkehr zwischen einem entfernten Server (es werden weltweit verschiedene Server zur Auswahl gestellt) und einer angegebenen URL.

Expires-Header -
Expires-Header - Conditional GET Requests

Als Beispiel wurde die Adresse des Webstandard-Blogs von einem Server aus Amsterdam mit DSL-Geschwindigkeit und dem Internet Explorer 7 getestet. Nachdem der Test abgeschlossen war, lieferte das Tool zwei Statistiken für einen ersten und einen wiederholten Aufruf der Seite. In unserem Fall ist die Statistik für den wiederholten Aufruf interessant.

Fehlende Expires-Header
Fehlende Expires-Header

Sämtliche dieser Requests werden vom Kulando-Server mit dem Statsucode 304 (Not Modified) beantwortet. In diesem Beispiel gilt das für ganze 27 Ressourcen und nimmt insgesamt ca. 1,5 Sekunden in Anspruch. Und all das nur, um festzustellen, dass der Browser die Ressourcen aus seinem Cache verwenden kann. Eine Untersuchung der Seite mit YSlow zeigt, dass diese Header tatsächlich nicht vorhanden sind.

Wie kann ein Expires-Header helfen?

Expires-Header - VerfallsdatumWird mit einer Ressource ein Expires-Header ausgeliefert, unterbindet dieser die Conditional GET Requests. Dem Browser wird durch diesen Header ein "Verfallsdatum" genannt. Bis zum Ablauf dieses Datums bezieht dieser die Ressource dann aus dem Cache, ohne nochmals mit dem Server zu kommunizieren. Im Idealfall zeigt dieses Verfallsdatum weit in die Zukunft (10 Jahre oder mehr), weshalb man von einem weit in die Zukunft weisenden Expires-Header (Far Future Expires-Header) spricht. Dieser spart unnötige HTTP Requests und somit auch Server-Ressourcen. Ein Expires-Header läßt sich unter Apache mit dem Modul mod_expires recht einfach konfigurieren. Untersucht man den Antwort-Header in der Browser-Extension Firebug, sieht man das das Verfallsdatum am 28. Juli 2025 (siehe roter Rahmen) endet. Allerdings ist die Sache damit noch nicht abgeschlossen. Denn zwangsläufig stellt sich nun folgende Frage:

Was mache ich, wenn sich die Ressource doch ändern sollte?

Die Antwort darauf findet Ihr im weiteren Verlauf dieser Artikelserie, die bereits diese Woche fortgesetzt wird.

Informationen über den Gastautoren

Nico Steiner ist Experte für Frontend-Technologien und entwickelt in diesem Bereich Strategien und Lösungen für die 1&1 Shopsysteme, die über 30 Web-Applikationen der Marken 1&1, WEB.DE und GMX umfassen. Sein Aufgabengebiet beinhaltet auch die fachliche Leitung zweier Frontend-Entwickler-Teams mit insgesamt 15 Mitarbeitern. Seine Arbeit ist durch die Vorgaben und Ideen der Webstandards geprägt und deckt nahezu den gesamten Bereich der Frontend-Entwicklung ab. Momentan optimiert er die Zugänglichkeit und Performance der 1&1 Shopsysteme und treibt deren Modularisierung voran.

Werde auch du Gastautor im Webstandard-Blog!

Um Themengebiete wie diese, für die sich die Leser interessieren anbieten zu können, möchten wir über diesem Wege weiterhin anderen Bloggern die Möglichkeit geben, ihr Fachwissen mit unseren Lesern teilen zu können. Voraussetzung ist lediglich, dass sich diese Artikel in den vorhanden Kategorien unseres Blogs untergebracht werden können und der jeweilige Autor über entsprechendes Fachwissen verfügt.

Ähnliche Artikel zum Thema Webseitenoptimierung
  1. Tamas Szalai
    18 Okt 2010, 10:38

    Hallo,

    erstmal großes Lob für den interessanten Artikel und ich freu mich auch schon auf die Fortsetzung. Ich hätte noch ein Frage bzgl. folgender Konfiguration: Wie, bzw. wo muss ich den expires-Header setzen, wenn die Bilder z.B. von einem nginx oder lighttpd bereitgestellt werden und diese via reverse_proxy vom Apache geladen werden? Übernimmt hier Apache auch das setzen des expires oder muss das dann der Content-HTTP-Server machen?


  2. Markus Möller
    18 Okt 2010, 11:17

    Oh, das scheint interessant (und praktisch) zu werden. Ich freue mich schon auf den nächsten Teil der Serie.


  3. Jakob
    18 Okt 2010, 12:01

    Hi, sehr schöner Artikel, allerdings bin ich mir über folgende Aussage zum Optimieren der Geschwindigkeit von Websiten nicht ganz sicher.

    "Stylesheets im Head des Dokuments zu platzieren, stellt auch keine große Hürde dar"

    Ich meine erst kürzlich etwas anderes gelesen zu haben. Nämlich dass Inline-CSS am besten in ein gesondertes Dokument kommen, da dies gecached wird und somit nur einmal geladen wird, wohingegen viele HTML Seiten gar nicht erst im Browsercache landen. Hab ich mich da verlesen, oder gibt es da andere Ansichten?

    MfG,
    Jakob


  4. E.T 18 Okt 2010, 13:04

    Vielen Dank für den interessanten Einstieg! Mit diesem Thema habe ich mich bisher nicht beschäftigt, da es kaum einen guten Überblick dazu gab - der Auftakt verspricht einiges, ich bin sehr auf die Fortsetzung gespannt. Übrigens lieber heute als morgen! :)

    Viele Grüße

    Andreas


  5. Christian Harms
    18 Okt 2010, 21:29

    Es gibt je nach Anwendungsfall verschiedene Cachemöglichkeiten. Für das Beispiel der statischen Dateien ist EIN Header ausreichend.

    Dein Beispiel schickt aber Expire und Cache-Control mit. Der Expire-Header wird ignoriert, wenn der Cache-Control-Header geschickt wird. Außerdem entspricht der Wert "mag-age: 466560000" Sekunden dem Expire-Datum. Und laut RFC 2616 wird ein Future-Expire nicht über 1 Jahr empfohlen - wohl um die lokalen Browsercache (wie auch Proxies) nicht zu übermüllen.

    Und die Auslaufzeit so weit in der Zukunft liegt, wird der Conditional-Request auf die Modified-Since nicht greifen.

    Fazit: Eine statt drei Headerzeilen reicht aus und damit ist auch noch etwas Traffik gespeichert.

    Gruß, Christian - ein Kollege ;-)


  6. Nico
    18 Okt 2010, 23:54

    Danke für euer Lob und Feedback.

    @Tamas: Da dieses Setting sehr speziell ist, würde ich an Deiner Stelle einfach mal verschiedene Szenarien durchspielen, und mit dem Firebug nachprüfen, bei welcher Konfiguration der Header beim Client ankommt.

    @Markus: Ja, der nächste Artikel wird sehr praktisch :-)

    @Jakob: Das ist richtig. Da sich das HTML von Seite zu Seite ändert, sollte das CSS aus einer externen Datei bezogen werden. Diese sollte dann im Head geladen werden, da der Browser erst dann das Rendering beginnt, wenn die Informationen aus den Stylesheets zur Verfügung stehen.

    @Christian: Es gibt einige Gründe, entweder beide Header oder sogar nur den Cache-Control Header anzugeben. Folgender Artikel geht darauf detaillierter ein: http://www.mnot.net/blog/2007/05/15/expires_max-age. Ich habe weiterhin festgestellt, dass ein Last-Modified-Header zusätzlich hilfreich ist, um dem Server bei einem expliziten Reload im Browser die Möglichkeit zu geben, mit einem 304 Code zu antworten. Beim Verfallsdatum habe ich mich an die Empfehlungen von Steve Souders gehalten (dessen Veröffentlichungen die Basis dieses Artikels bilden). Andere Quellen empfehlen, wie Du auch, 1 Jahr.


  7. Markus
    19 Okt 2010, 19:16

    Ein Klassiker. Muss man sich nur mal ausrechnen, wieviel datenübertragung man sich damit noch ersparen kann. Bei großen Seiten spart man dadurch nicht nur Zeit, sondern auch Geld.


  8. Tim
    21 Okt 2010, 22:37

    Ich entwickle im Moment ein wenig an staticwebspeed.com (Webseite und Skript). Habe das bereits bei ein paar Webseiten im Einsatz und es ist wirklich praktisch... vielleicht hast du ja auch Ideen was fehlt... oder findest Anregungen um deinen Post zu ergänzen... Grüße, Tim


  9. Rick 24 Okt 2010, 18:46

    Hi,

    wir sind unlängst auch über das Thema Header Expire gestolpert (Chrome) und haben eine Präsenz dahingehend optimiert. Die Einsparung ist eher gering ausgefallen, was v.a. daran liegt, dass nur wenige Besucher lange bleiben. Bei Projekten mit sehr hoher PI/Visit ist die Optimierung hier aber ein Muss!

    @Jacob: Ja, CSS gehört in eine gesonderte Datei, eben damit man von deren Caching profitiert.


  10. Valentin 28 Okt 2010, 17:47

    Hey, danke! Bin gerade dabei, meinen Blog zu optimieren und darunter fällt auch die Performance zu verbessern. Ich werde mir deine Beiträge noch genauer anschauen und hoffentlich auch verwenden können :)


  11. Siegfried
    24 Nov 2010, 15:32

    Hmmm, können dynamisch erzeugte Dateien überhaupt gecached werden? Wenn ich mich richtig erinnere, übergeht der Browser bei allen URLs, die auf eine dynamische Generierung hinweisen, den Cache.

    Aber immerhin kann man ja statische Teile wie Bilder, Stylesheets und dergleichen gut statisch und damit cachebar machen.

    Zu dem Thema gibt es übrigens ein gutes Buch von O'Reilly: Web Caching von Duane Wessels, dem Schöpfer von Sqid.


  12. derMaggus
    11 Feb 2011, 11:30

    Hallo,

    mich interessiert das Thema aktuell brennend. Wo bleibt die Zugabe, welche bereits eine Woche später erscheinen sollte?

    Liebe Grüße,
    Marcus


  13. Thomas Rith
    15 Jul 2011, 15:05

    Hi,
    das Thema interessiert mich, aber irgendwie checke ich es nicht ganz... :)

    Ich bin auf Googles Speed Online Test gewesen. Dort wird einem gesagt, dass hier und da was zu verbessern ist. Unter anderem bin ich da auf dieses Thema gestoßen.

    Nun im Test hatte ich "auszugsweise" diese Angaben.
    http://www.und-geld.de/.../style.css (Ablauf nicht festgelegt)
    http://www.und-geld.de/.../icon_smile.gif (Ablauf nicht festgelegt)
    http://0.gravatar.com/.../ad516503a11cd5ca435acc9bb6523536?... (5 Minuten)
    http://0.gravatar.com/.../ad516503a11cd5ca435acc9bb6523536?... (5 Minuten)

    Ich wäre wirklich sehr dankbar, wenn mir das einer mal, für Laien, erklären könnte, wieso das eine 5 Minuten zeigt, und das andere nicht festgelegt ist, bzw. wie ich das angeben muss. Ich werde da nicht schlau draus und finde, für mich, keine logischen Erklärungen im Netz darüber... :(

    LG
    Thomas


  14. Woj 01 Okt 2011, 20:55

    @ Thomas

    Ich glaub da geht es um das Ablaufdatum des Cache welches du festlegen kannst. Damit sagst du dem Clienten nach welcher Zeit er die Datei neu Laden soll.

    Korigiert mich bitte wenn ich falsch liege

    mfg


  15. Holger 02 Mär 2013, 20:40

    Funktionieren die Expires-Header Angebaen nur bei Dateien, welche auf den gleichen Server liegen?

    Ich hab meine htaccess mit entsprechenden angaben erweitert. Bei einem Test über gtmetrix.com ist der Wert für diesen Punkt somit auch besser, es werden allerdings immernoch dateien ohne oder mit sehr kurzem header-expire angezeigt. Dabei handelt es sich um externe dateien.

    Kann ich die Cachedauer externer Dateien in meinen Dokumenten irgendwie festlegen?


Artikel kommentieren





HTML ist erlaubt und ausdrücklich erwünscht, wobei folgende Tags eingesetzt werden können: <a href="" title=""></a> <b></b> <cite></cite> <code></code> <em></em> <strong></strong>


authimage