Mit Expires-Header die Performance von Websites verbessern - Der MD5-Hash

Mit Expires-Header die Performance von Websites verbessernExpires-Header - Im ersten Teil wurde gezeigt, wie sich die Performance von Websites mit Expires Headern verbessern läßt. Dieser Artikel soll die Frage beantworten, wie ein Neuladen einer Ressource erzwungen werden kann, wenn sich diese doch ändern sollte. Ein Browser bezieht eine Ressource mit Expires Headern vor Ablauf ihres Verfallsdatums immer aus dem Cache. Ein Neuladen kann zuverlässig nur durch eine Änderung der Adresse der Ressource erzwungen werden. Dabei sollte sich die URL natürlich nur dann ändern, wenn sich die Daten der Ressource ändern. Man bedient sich dabei eines MD5-Hashs, welcher als kurze Repräsentanz der Daten einer Ressource in deren URL integriert wird.

Wie erzwinge ich ein Neuladen einer veränderten Ressource?

Der Trick besteht darin, dass sich dieser MD5-Hash (und somit auch die URL der Ressource) nur dann ändert, wenn sich auch die Daten der Ressource ändern.

Aus einer "normalen" URL zum Abruf einer Grafik ui_logo.gif:
http://www.uicdn.net/ui/ui_logo.gif

wird dabei eine solche URL:
http://www.uicdn.net/ui/2f52dd21bb608d3a3614288a7e45730e-ui_logo.gif

Nur in diesem Fall kommt es zu einem erneuten Request. Verändert sich die Ressource nicht, verändert sich auch nicht der MD5-Hash - die Adresse bleibt die selbe und die Ressource wird weiterhin aus dem Cache bezogen.

Wie sieht das nun in der Praxis aus?

Die elegante Lösung sieht vor, während des Publizierens der Website die beschriebenen Hash-Tags in die Grafiknamen zu integrieren. Leider ist dies ein recht aufwändiger Schritt, und erklärt, warum viele Seiten auf den Einsatz von Expires Header verzichten. Für große Websites mit entsprechend viel Traffic ist dies jedoch eine lohnende Investition, da sich dadurch sowohl die Ladezeit als auch die Serverlast merklich verringern lassen.

Ein Browser bezieht eine Ressource mit Expires Headern vor Ablauf ihres Verfallsdatums immer aus dem Cache. Ein Neuladen kann zuverlässig nur durch eine Änderung der Adresse der Ressource erzwungen werden.

Für kleinere Websites, deren Ressourcen sich im Nachhinein nicht häufig ändern, wäre eventuell ein "Pi-mal-Daumen" Expires-Header mit "normalen" URLs denkbar - basierend auf eigenen Erfahrungen des Websitebetreibers ("Mein CSS ändert sich höchstens einmal im Monat"). Dabei besteht natürlich die Gefahr, das ein Neuladen im richtigen Moment ausbleibt.

Ein Content Delivery Server muss her!

Möchte man sich auf das Glücksspiel mit einem geschätzen Expires-Header nicht einlassen, bleibt nur die aufwändige Lösung. Folgende Grafik soll verdeutlichen, welche Schritte dabei beachtet werden müssen.

Content Delivery Server - Schaubild
Content Delivery Server - Schaubild

Sämtliche Grafiken (CSS, JavaScript, Flash oder PDFs wären weitere Kandidaten) müssen während des Publizierens als MD5-Hash-Variante auf einen Content Delivery Server kopiert werden. Ob dafür ein eigener Rechner nötig ist, hängt dabei vom Umfang des Traffics ab. Wichtig ist nur, dass die kopierten Ressourcen von einem Webserver ausgeliefert werden. Auf diesem Server müssen dann natürlich die Far Future Expires Header konfiguriert sein. Weiterhin ist es nötig, sämtliche HTML-Dokumente und Stylesheets auf entsprechende Pfade zu parsen und diese durch die MD5-Hash-Variante zu ersetzen, damit die Ressourcen auch vom Content Delivery Server und nicht von ihrer ursprünglichen URL abgerufen werden. Dabei empfiehlt es sich, nicht zuletzt für dynamisch generierte Pfade, die Ressourcen unter den ursprünglichen URLs als Fallback weiterhin anzubieten.

Im dritten Teil dieser Artikelserie werdet Ihr erfahren, welche weiteren Optimierungen möglich sind, wenn statische Ressourcen zentral über einen eigenen Server ausgeliefert werden.

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. Thomas Scholz
    20 Okt 2010, 16:22

    MD5 ist nicht kollisionssicher: Zwei unterschiedliche Entitäten können zum selben Hash führen. Kürzer, verständlicher und zuverlässiger ist ein UNIX-Timestamp. So verfahre ich mit Stylesheets und Scripten.


  2. Markus Möller
    20 Okt 2010, 16:34

    Wie wäre es, wenn man den md5-Wert nicht zum Dateinamen macht, sondern einfach per URL-Parameter dranhängt?

    Also anstatt
    http://www.uicdn.net/ui/2f52dd21bb608d3a3614288a7e45730e-ui_logo.gif

    ein
    http://www.uicdn.net/ui/ui_logo.gif?2f52dd21bb608d3a3614288a7e45730e

    oder
    http://www.uicdn.net/ui/ui_logo.gif?md5=2f52dd21bb608d3a3614288a7e45730e

    Der Browser würde doch trotzdem die URL neu anfragen und das Bild müsste nicht umbenannt werden.

    Gehen wir davon aus, dass alle Seiten dynamisch sind, kann man (z.B. in PHP) das hier machen:


  3. Arnold 20 Okt 2010, 19:03

    Wurde der PHP Code hier extra "ausgeschnitten"? Ich sehe nämlich nichts.


  4. Nico
    20 Okt 2010, 22:27

    @Thomas: Kollisionssicher ist es nicht, aber kombiniert mit dem Dateinamen ist die Wahrscheinlichkeit einer Kollision doch sehr gering. Deine Timestamp-Variante finde ich sehr interessant. Leider werden die Stylesheets und Scripte in meinem Fall dynamisch generiert und kombiniert, was die Ermittlung eines solchen Timestamps wohl unmöglich macht. Für statische Ressourcen stellt er auf jeden Fall eine Alternative dar. Allerdings planen wir für unseren Content Delivery Server, sämtliche Grafiken während des Publish mit Smush.it "on the fly" zu optimieren, welches den Timestamp bei jedem Publish verändern würde. Für unsere Fälle ist ein MD5-Hash deshalb zuverlässiger.

    @Markus: Auch ein interessanter Vorschlag. Die Google Imagesuche wäre mit dieser Variante bestimmt happy :-) Ich habe in dem Artikel nicht erwähnt, dass beim Umschreiben die unterschiedlichen Pfade zu (gleichen) Ressourcen "wegoptimiert" und zu einem Verzeichnis verkürzt werden können. Gleiche Grafiken werden dann, dank des identischen MD5-Hashs, von der selben URL bezogen, auch wenn sie ursprünglich aus verschiedenen Verzeichnissen bezogen wurden. Existieren in diesem Fall jedoch unterschiedliche Grafiken mit gleichem Namen, muss der Hash im Grafiknamen integriert sein, die Angabe als Parameter reicht dann nicht aus.

    Zugegeben sind meine Schilderungen spezielle Fälle, weshalb eure Vorschläge für geeignete Websites bestimmt die bessere Wahl darstellen. Man sollte sich deshalb vorher genau ansehen, welche Anforderungen sich aus dem eigenen System heraus an das Umschreiben der URLs ergeben.


  5. Tom
    21 Okt 2010, 09:40

    @Nico:
    Grafiken "on the fly" komprimieren? Für jeden Besucher? Das dürfte länger dauern als die normale Übertragung. Sowas macht man schon vor dem Bereitstellen. Oder beim Upload einmal.
    Ich hoffe auch im Namen deiner Server-CPU, dass ich da was falsch verstanden habe. ;)


  6. Schepp
    21 Okt 2010, 11:24

    @Tom Deswegen steht da ja auch ein "während des Publish" ;)

    @Markus Query-Strings anzuhängen hat den Nachteil, dass Proxies die Dateien dann extra nicht zwischenspeichern. Damit würde der Beschelunigungseffekt wieder ausgehebelt. Man muss das irgendwie maskieren, idealerweise, indem man es serverseitig per mod_rewrite umbiegt (siehe weiter unten).

    Ich bin auch Anhänger davon, den Timestamp zu verwenden, wie @Thomas es vorschlägt. Das dürfte auch deutlich flotter gehen, als den Hash aus Binärdaten zu erzeugen.

    Was das CDN angeht: Warum arbeitest Du nicht mit einem Origin-Pull CDN in Kombination mit mod_rewrite auf Deinem Server? Wäre viel simpler. Dann packst Du nämlich in die .htaccess Deines Servers einfach eine Regel rein, die da lautet:

    RewriteEngine on
    RewriteRule ^ui/[\da-f]{32}\-(.*)$ ui/$1 [L]

    (im Falle des MD5-Systems) und somit zieht sich das Origin-Pull CDN immer den aktuellsten Stand von Deinem Server, ohne dass Du es jedesmal proaktiv bestücken musst.

    Ansonsten: Webseite Performance Optimization FTW! :)


  7. Nico
    21 Okt 2010, 19:52

    @Schepp: Mußte mich erst einmal über diese Technologie schlau machen ;-) Die Kombination mit der Rewrite Rule würde vorraussetzen, dass die Pfade zu den Ressourcen erhalten bleiben (ich hatte das in meinem ersten Kommentar beschrieben) und dass das CDN von nur einer Web-Applikation mit Ressourcen versorgt wird. Ok, man könnte weitere Regeln hinzufügen, um die Pfade zu den verschiedenen Applikationen aufzulösen. Wir haben uns für den proaktiven Ansatz vor allem deshalb entschieden, weil die enorme Anzahl an CDS-Requests über einen Load Balancer auf mehrere Rechner verteilt werden und dadurch gerade im Moment des Publish nebenläufige Zugriffe sehr wahrscheinlich sind. In dieser Konstellation erschien uns der gewählte Ansatz am wenigsten problematisch. Für weniger komplexe Situationen ist Dein Ansatz eine tolle Sache.

    Ich bin begeistert, wie viele coole Ideen hier zur Sprache kommen :-)


  8. Weber 22 Okt 2010, 19:07

    Manche Leute fragen mich: "Was kann man mit Photoshop erstellen?" ind ich frage immer was kann man nicht mit Photoshop erstellen?
    Mit Adobe Photoshop kann man nicht nur Kreatives Webdesign Etwikeln, sondern auch Fotos bearbeiten. Noch 20 Jahre her haben wir alle mit dem Pinzel gezeichnet, heutzutage machen wir alles mit dem Computer.


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