Unnötige Netzwerkanfragen mit dem HTTP-Cache vermeiden

Das Abrufen von Ressourcen über das Netzwerk ist sowohl langsam als auch teuer:

  • Große Antworten erfordern viele Rücksprünge zwischen dem Browser und dem Server.
  • Ihre Seite wird erst geladen, wenn alle kritischen Ressourcen vollständig heruntergeladen wurden.
  • Wenn ein Nutzer mit einem begrenzten Datentarif auf Ihre Website zugreift, ist jede unnötige Netzwerkanfrage eine Verschwendung seines Geldes.

Wie können Sie unnötige Netzwerkanfragen vermeiden? Der HTTP-Cache des Browsers ist die erste Verteidigungslinie. Dieser Ansatz ist nicht unbedingt der leistungsstärkste oder flexibelste und Sie haben nur begrenzte Kontrolle über die Lebensdauer der im Cache gespeicherten Antworten. Er ist jedoch effektiv, wird in allen Browsern unterstützt und erfordert nicht viel Arbeit.

In diesem Leitfaden erfahren Sie die Grundlagen einer effektiven HTTP-Caching-Implementierung.

Browserkompatibilität

Es gibt keine einzelne API namens HTTP-Cache. Das ist der allgemeine Name für eine Sammlung von Webplattform-APIs. Diese APIs werden in allen Browsern unterstützt:

Cache-Control

Browser Support

  • Chrome: 1.
  • Edge: 12.
  • Firefox: 1.
  • Safari: 1.

Source

ETag

Browser Support

  • Chrome: 1.
  • Edge: 12.
  • Firefox: 1.
  • Safari: 1.

Source

Last-Modified

Browser Support

  • Chrome: 1.
  • Edge: 12.
  • Firefox: 1.
  • Safari: 1.

Source

Funktionsweise des HTTP-Cache

Alle HTTP-Anfragen, die der Browser stellt, werden zuerst an den Browsercache weitergeleitet, um zu prüfen, ob eine gültige im Cache gespeicherte Antwort vorhanden ist, die zur Erfüllung der Anfrage verwendet werden kann. Wenn eine Übereinstimmung gefunden wird, wird die Antwort aus dem Cache gelesen. Dadurch werden sowohl die Netzwerklatenz als auch die Datenkosten für die Übertragung vermieden.

Das Verhalten des HTTP-Caches wird durch eine Kombination aus Anfrageheadern und Antwortheadern gesteuert. Im Idealfall haben Sie sowohl die Kontrolle über den Code Ihrer Webanwendung (der die Anfrageheader bestimmt) als auch über die Konfiguration Ihres Webservers (der die Antwortheader bestimmt).

Eine ausführlichere konzeptionelle Übersicht finden Sie im MDN-Artikel HTTP-Caching.

Anfrageheader: Verwenden Sie in der Regel die Standardeinstellungen.

Es gibt eine Reihe wichtiger Header, die in den ausgehenden Anfragen Ihrer Webanwendung enthalten sein sollten. Der Browser sorgt jedoch fast immer dafür, dass sie in Ihrem Namen festgelegt werden, wenn er Anfragen stellt. Anfrageheader, die sich auf die Überprüfung der Aktualität auswirken, wie If-None-Match und If-Modified-Since, werden basierend auf der Interpretation der aktuellen Werte im HTTP-Cache durch den Browser angezeigt.

Das ist eine gute Nachricht: Sie können weiterhin Tags wie <img src="my-image.png"> in Ihren HTML-Code einfügen und der Browser übernimmt das HTTP-Caching automatisch für Sie, ohne dass Sie etwas dafür tun müssen.

Antwortheader: Webserver konfigurieren

Der wichtigste Teil der HTTP-Caching-Einrichtung sind die Header, die Ihr Webserver jeder ausgehenden Antwort hinzufügt. Die folgenden Header spielen alle eine Rolle für ein effektives Caching-Verhalten:

  • Cache-Control: Der Server kann eine Cache-Control-Anweisung zurückgeben, um anzugeben, wie und wie lange der Browser und andere Zwischen-Caches die einzelne Antwort im Cache speichern sollen.
  • ETag: Wenn der Browser eine abgelaufene im Cache gespeicherte Antwort findet, kann er ein kleines Token (in der Regel ein Hash des Dateiinhalts) an den Server senden, um zu prüfen, ob sich die Datei geändert hat. Wenn der Server dasselbe Token zurückgibt, ist die Datei identisch und muss nicht noch einmal heruntergeladen werden.
  • Last-Modified: Dieser Header dient demselben Zweck wie ETag, verwendet aber eine zeitbasierte Strategie, um zu ermitteln, ob sich eine Ressource geändert hat, im Gegensatz zur inhaltsbasierten Strategie von ETag.

Einige Webserver unterstützen standardmäßig die Einrichtung dieser Header, während andere sie nur dann einfügen, wenn Sie sie explizit konfigurieren. Die spezifischen Details zur Konfiguration von Headern variieren stark je nach verwendetem Webserver. Die genaue Vorgehensweise finden Sie in der Dokumentation Ihres Servers.

Hier finden Sie eine Anleitung zum Konfigurieren einiger beliebter Webserver:

Wenn Sie den Cache-Control-Antwortheader weglassen, wird das HTTP-Caching nicht deaktiviert. Stattdessen raten Browser, welches Caching-Verhalten für eine bestimmte Art von Inhalt am sinnvollsten ist. Wahrscheinlich möchten Sie mehr Kontrolle als diese Option bietet. Nehmen Sie sich also die Zeit, Ihre Antwortheader zu konfigurieren.

Welche Antwortheader-Werte sollten Sie verwenden?

Es gibt zwei wichtige Szenarien, die Sie bei der Konfiguration der Antwortheader Ihres Webservers berücksichtigen sollten.

Langlebiges Caching für versionierte URLs

Angenommen, Ihr Server weist Browser an, eine CSS-Datei für ein Jahr (Cache-Control: max-age=31536000) im Cache zu speichern, Ihr Designer hat aber gerade ein Notfallupdate durchgeführt, das Sie sofort implementieren müssen. Wie benachrichtigen Sie Browser, die veraltete Cache-Kopie der Datei zu aktualisieren? Das ist nicht möglich, zumindest nicht ohne die URL der Ressource zu ändern.

Nachdem der Browser die Antwort im Cache gespeichert hat, wird die im Cache gespeicherte Version verwendet, bis sie gemäß max-age oder expires nicht mehr aktuell ist oder bis sie aus einem anderen Grund aus dem Cache entfernt wird, z. B. wenn der Nutzer den Browsercache leerte. Daher verwenden verschiedene Nutzer möglicherweise unterschiedliche Versionen der Datei, wenn die Seite erstellt wird: Nutzer, die die Ressource gerade abgerufen haben, verwenden die neue Version, während Nutzer, die eine frühere (aber noch gültige) Kopie im Cache haben, eine ältere Version der Antwort verwenden.

Wie können Sie das Beste aus beiden Welten nutzen: clientseitiges Caching und schnelle Updates? Sie ändern die URL der Ressource und zwingen den Nutzer, die neue Antwort herunterzuladen, sobald sich die Inhalte ändern. Normalerweise geschieht dies, indem ein Fingerabdruck der Datei oder eine Versionsnummer in den Dateinamen eingebettet wird, z. B. style.x234dff.css.

Wenn Sie auf Anfragen für URLs antworten, die einen Fingerabdruck oder Versionsinformationen enthalten und deren Inhalt sich nicht ändern soll, fügen Sie Ihren Antworten Cache-Control: max-age=31536000 hinzu.

Wenn Sie diesen Wert festlegen,wird dem Browser mitgeteilt,dass er den Wert im HTTP-Cache sofort verwenden kann, wenn er die gleiche URL innerhalb des nächsten Jahres (31.536.000 Sekunden; der maximal unterstützte Wert) laden muss, ohne eine Netzwerkanfrage an Ihren Webserver senden zu müssen. Das ist großartig. Sie profitieren sofort von der Zuverlässigkeit und Geschwindigkeit, die Sie durch die Umgehung des Netzwerks erhalten.

Mit Build-Tools wie webpack lässt sich der Prozess zur Zuweisung von Hash-Fingerabdrücken zu Ihren Asset-URLs automatisieren.

Serverüberprüfung für nicht versionierte URLs

Leider sind nicht alle von Ihnen geladenen URLs versioniert. Vielleicht können Sie vor dem Bereitstellen Ihrer Webanwendung keinen Buildschritt einschließen, sodass Sie Ihren Asset-URLs keine Hashes hinzufügen können. Außerdem benötigt jede Webanwendung HTML-Dateien. Diese Dateien enthalten (fast) nie Versionsinformationen, da sich niemand die Mühe machen wird, Ihre Webanwendung zu verwenden, wenn er sich merken muss, dass die zu besuchende URL https://example.com/index.34def12.html lautet. Was können Sie also mit diesen URLs tun?

In diesem Fall müssen Sie sich geschlagen geben. Das HTTP-Caching allein ist nicht leistungsfähig genug, um das Netzwerk vollständig zu umgehen. Keine Sorge, Sie erfahren bald mehr über Service Worker, die uns die nötige Unterstützung bieten, um das Blatt wieder zu Ihren Gunsten zu wenden. Es gibt jedoch einige Schritte, mit denen Sie dafür sorgen können, dass Netzwerkanfragen so schnell und effizient wie möglich sind.

Mit den folgenden Cache-Control-Werten können Sie optimieren, wo und wie nicht versionierte URLs zwischengespeichert werden:

  • no-cache. Dadurch wird der Browser angewiesen, die URL jedes Mal noch einmal beim Server zu validieren, bevor eine zwischengespeicherte Version verwendet wird.
  • no-store. Dadurch werden der Browser und andere Zwischen-Caches (z. B. CDNs) angewiesen, keine Version der Datei zu speichern.
  • private. Browser können die Datei im Cache speichern, Zwischen-Caches jedoch nicht.
  • public. Die Antwort kann in jedem Cache gespeichert werden.

Im Anhang: Cache-Control-Flussdiagramm wird die Entscheidung, welche Cache-Control-Werte verwendet werden sollen, veranschaulicht. Cache-Control kann auch eine durch Kommas getrennte Liste von Anweisungen akzeptieren. Siehe Anhang: Cache-Control Beispiele.

Es kann auch hilfreich sein, ETag oder Last-Modified festzulegen. Wie bereits unter Antwortheader erwähnt, dienen ETag und Last-Modified demselben Zweck: Sie bestimmen, ob der Browser eine abgelaufene im Cache gespeicherte Datei noch einmal herunterladen muss. Wir empfehlen die Verwendung von ETag, da es genauer ist.

Angenommen, seit dem ersten Abruf sind 120 Sekunden vergangen und der Browser hat eine neue Anfrage für dieselbe Ressource gestartet. Der Browser prüft zuerst den HTTP-Cache und findet die vorherige Antwort. Leider kann der Browser die vorherige Antwort nicht verwenden, da sie abgelaufen ist. An diesem Punkt kann der Browser eine neue Anfrage senden und die neue vollständige Antwort abrufen. Das ist jedoch ineffizient, da es keinen Grund gibt, dieselben Informationen herunterzuladen, die sich bereits im Cache befinden, wenn sich die Ressource nicht geändert hat.

Genau dieses Problem sollen Validierungstokens, wie im ETag-Header angegeben, lösen. Der Server generiert und gibt ein beliebiges Token zurück, das in der Regel ein Hash oder ein anderer Fingerabdruck des Inhalts der Datei ist. Der Browser muss nicht wissen, wie der Fingerabdruck generiert wird, sondern muss ihn nur bei der nächsten Anfrage an den Server senden. Wenn der Fingerabdruck unverändert ist, hat sich die Ressource nicht geändert und der Browser kann den Download überspringen.

Wenn du ETag oder Last-Modified festlegst, wird die Anfrage zur erneuten Validierung viel effizienter, da die Anfrageheader If-Modified-Since oder If-None-Match ausgelöst werden, die unter Anfrageheader erwähnt werden.

Wenn ein richtig konfigurierter Webserver diese eingehenden Anfrageheader sieht, kann er prüfen, ob die Version der Ressource, die der Browser bereits in seinem HTTP-Cache hat, mit der neuesten Version auf dem Webserver übereinstimmt. Wenn eine Übereinstimmung vorliegt, kann der Server mit einer 304 Not Modified-HTTP-Antwort antworten, was dem Äquivalent von „Hey, benutze einfach das, was du schon hast!“ entspricht. Bei dieser Art von Antwort müssen nur sehr wenige Daten übertragen werden. Daher ist sie in der Regel viel schneller als das Zurücksenden einer Kopie der angeforderten Ressource.

Eine Visualisierung eines Clients, der eine Ressource anfordert, und des Servers, der mit einem 304-Header antwortet.
Der Browser fordert /file vom Server an und fügt den Header If-None-Match hinzu, um den Server anzuweisen, nur die vollständige Datei zurückzugeben, wenn der ETag der Datei auf dem Server nicht mit dem If-None-Match-Wert des Browsers übereinstimmt. In diesem Fall stimmen die beiden Werte überein. Daher gibt der Server eine 304 Not Modified-Antwort mit einer Anleitung zurück, wie lange die Datei im Cache gespeichert bleiben soll (Cache-Control: max-age=120).

Zusammenfassung

Der HTTP-Cache ist eine effektive Möglichkeit, die Ladeleistung zu verbessern, da unnötige Netzwerkanfragen reduziert werden. Sie wird in allen Browsern unterstützt und die Einrichtung ist nicht sehr aufwendig.

Die folgenden Cache-Control-Konfigurationen sind ein guter Ausgangspunkt:

  • Cache-Control: no-cache für Ressourcen, die vor jeder Verwendung noch einmal mit dem Server validiert werden sollten.
  • Cache-Control: no-store für Ressourcen, die niemals im Cache gespeichert werden sollen.
  • Cache-Control: max-age=31536000 für versionierte Ressourcen.

Mit dem ETag- oder Last-Modified-Header können Sie abgelaufene Cache-Ressourcen effizienter neu validieren.

Weitere Informationen

Wenn Sie mehr über die Verwendung des Cache-Control-Headers erfahren möchten, lesen Sie den Leitfaden Best Practices für das Caching und Fallstricke bei der Angabe von „max-age“ von Jake Archibald.

Unter Cache lieben erfahren Sie, wie Sie die Cache-Nutzung für wiederkehrende Besucher optimieren.

Anhang: Weitere Tipps

Wenn Sie mehr Zeit haben, können Sie die Nutzung des HTTP-Caches auch so optimieren:

  • Verwenden Sie einheitliche URLs. Wenn Sie dieselben Inhalte über unterschiedliche URLs bereitstellen, werden diese Inhalte mehrmals abgerufen und gespeichert.
  • Minimieren Sie die Abwanderung. Wenn ein Teil einer Ressource (z. B. eine CSS-Datei) häufig aktualisiert wird, der Rest der Datei jedoch nicht (z. B. Bibliothekcode), sollten Sie den Code, der häufig aktualisiert wird, in eine separate Datei aufteilen und eine Caching-Strategie mit kurzer Dauer für den Code mit häufigen Aktualisierungen und eine Caching-Strategie mit langer Dauer für den Code verwenden, der sich nicht oft ändert.
  • Sehen Sie sich die neue Richtlinie stale-while-revalidate an, wenn in Ihrer Cache-Control-Richtlinie ein gewisser Grad an Aktualität akzeptabel ist.

Anhang: Cache-Control-Flussdiagramm

Flussdiagramm
Der Entscheidungsprozess für die Festlegung Ihrer Cache-Control-Header.

Anhang: Cache-Control-Beispiele

Cache-Control Wert Erklärung
max-age=86400 Die Antwort kann von Browsern und Zwischen-Caches bis zu einem Tag (60 Sekunden × 60 Minuten × 24 Stunden) im Cache gespeichert werden.
private, max-age=600 Die Antwort kann vom Browser (aber nicht von Zwischen-Caches) bis zu 10 Minuten (60 Sekunden × 10 Minuten) lang im Cache gespeichert werden.
public, max-age=31536000 Die Antwort kann ein Jahr lang in einem beliebigen Cache gespeichert werden.
no-store Die Antwort darf nicht im Cache gespeichert werden und muss bei jeder Anfrage vollständig abgerufen werden.