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 Umläufe zwischen dem Browser und dem Server.
  • Ihre Seite wird erst geladen, wenn alle wichtigen Ressourcen vollständig heruntergeladen wurden.
  • Wenn ein Nutzer auf Ihrer Website einen Tarif mit eingeschränkter mobiler Datennutzung hat, ist jede unnötige Netzwerkanfrage Geldverschwendung.

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

In diesem Leitfaden werden die Grundlagen einer effektiven HTTP-Caching-Implementierung beschrieben.

Browserkompatibilität

Der HTTP-Cache ist der allgemeine Name für eine Sammlung von Webplattform-APIs, die in allen Browsern unterstützt werden:

Cache-Control

Unterstützte Browser

  • Wahr
  • 12
  • Wahr
  • Wahr

Quelle

ETag

Unterstützte Browser

  • Wahr
  • 12
  • Wahr
  • Wahr

Quelle

Last-Modified

Unterstützte Browser

  • Wahr
  • 12
  • Wahr
  • Wahr

Quelle

Funktionsweise des HTTP-Cache

Alle HTTP-Anfragen des Browsers werden zuerst an den Browsercache weitergeleitet, um zu prüfen, ob im Cache eine gültige Antwort vorhanden ist, die zum Ausführen der Anfrage verwendet werden kann. Bei einer Übereinstimmung wird die Antwort aus dem Cache gelesen, wodurch sowohl die Netzwerklatenz als auch die Datenkosten der Übertragung entfallen.

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

Eine ausführlichere konzeptionelle Übersicht findest du im MDN-Artikel HTTP-Caching.

Anfrageheader: (normalerweise) Standardeinstellungen beibehalten

In den ausgehenden Anfragen Ihrer Webanwendung sollten einige wichtige Header enthalten sein. Der Browser legt sie jedoch fast immer für Sie fest, wenn er Anfragen sendet. Anfrageheader, die sich auf die Aktualitätsprüfung auswirken, wie If-None-Match und If-Modified-Since, werden basierend darauf angezeigt, ob der Browser die aktuellen Werte im HTTP-Cache versteht.

Das bedeutet, dass Sie weiterhin Tags wie <img src="my-image.png"> in Ihren HTML-Code einfügen können und der Browser das HTTP-Caching für Sie automatisch ohne zusätzlichen Aufwand übernimmt.

Antwortheader: Webserver konfigurieren

Der wichtigste Teil der HTTP-Caching-Einrichtung sind die Header, die Ihr Webserver jeder ausgehenden Antwort hinzufügt. Die folgenden Header fließen alle in ein effektives Caching-Verhalten ein:

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 die Datei geändert wurde. 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 jedoch eine zeitbasierte Strategie, um festzustellen, ob eine Ressource geändert wurde, im Gegensatz zur inhaltsbasierten Strategie von ETag.

Einige Webserver bieten eine integrierte Unterstützung für die standardmäßige Einstellung dieser Header. Andere lassen die Header vollständig weg, sofern Sie sie nicht explizit konfigurieren. Die spezifischen Details zur Konfiguration von Headern variieren je nach verwendetem Webserver stark. Die genauesten Details finden Sie in der Dokumentation Ihres Servers.

Im Folgenden finden Sie Anweisungen zur Konfiguration einiger häufig verwendeter Webserver:

Das Weglassen des Cache-Control-Antwortheaders deaktiviert das HTTP-Caching nicht. Stattdessen schätzen Browser effektiv, welche Art von Caching-Verhalten für einen bestimmten Inhaltstyp am sinnvollsten ist. Wahrscheinlich möchten Sie mehr Kontrolle haben, als das bietet, und müssen sich daher die Zeit nehmen, Ihre Antwortheader zu konfigurieren.

Welche Werte für den Antwortheader sollten Sie verwenden?

Es gibt zwei wichtige Szenarien, die Sie beim Konfigurieren der Antwortheader Ihres Webservers behandeln sollten.

Langlebiges Caching für versionierte URLs

Wie sich versionierte URLs für Ihre Caching-Strategie eignen
Versionierte URLs sind eine bewährte Methode, da sie die Entwertung von im Cache gespeicherten Antworten erleichtern.

Angenommen, Ihr Server weist Browser an, eine CSS-Datei ein Jahr lang im Cache zu speichern (Cache-Control: max-age=31536000), aber Ihr Designer hat gerade ein Notfallupdate durchgeführt, das Sie sofort implementieren müssen. Wie werden Browser aufgefordert, die „veraltete“ im Cache gespeicherte Kopie 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 so lange verwendet, bis sie gemäß max-age oder expires nicht mehr aktuell ist oder aus einem anderen Grund aus dem Cache entfernt wird, z. B. durch das Leeren des Browsercache durch den Nutzer. Daher können verschiedene Nutzer beim Erstellen der Seite unterschiedliche Versionen der Datei laden: Nutzer, die die Ressource gerade abgerufen haben, verwenden die neue Version, Nutzer, die eine frühere, aber noch gültige Kopie im Cache gespeichert haben, verwenden eine ältere.

Wenn Sie sowohl clientseitiges Caching als auch schnelle Updates erhalten möchten, können Sie die URL der Ressource ändern und den Nutzer auffordern, die neue Antwort herunterzuladen, wenn sich ihr Inhalt ändert. Dazu betten Sie in der Regel einen Fingerabdruck der Datei oder eine Versionsnummer in den Dateinamen ein, z. B. style.x234dff.css.

Wenn Sie auf Anfragen nach URLs antworten, die „fingerprint“ oder Versionsinformationen enthalten und deren Inhalte sich nie ändern sollen, fügen Sie Cache-Control: max-age=31536000 in Ihre Antworten ein.

Wenn Sie diesen Wert festlegen, kann der Browser, wenn im Laufe des nächsten Jahres die gleiche URL geladen werden muss (maximal unterstützter Wert 31.536.000 Sekunden), den Wert im HTTP-Cache sofort verwenden, ohne eine Netzwerkanfrage an Ihren Webserver senden zu müssen. Das ist großartig – Sie haben sofort die Zuverlässigkeit und Geschwindigkeit gesteigert, die sich aus der Umgehung des Netzwerks ergeben.

Build-Tools wie Webpack können den Prozess zum Zuweisen von Hash-Fingerabdrücken zu Ihren Asset-URLs automatisieren.

Erneute Servervalidierung für URLs ohne Version

Leider haben nicht alle URLs, die Sie laden, versionierte URLs. Eventuell können Sie vor der Bereitstellung der Webanwendung keinen Build-Schritt einbinden und somit auch keine Hashes zu Ihren Asset-URLs hinzufügen. Außerdem benötigt jede Webanwendung HTML-Dateien, die fast nie Versionsinformationen enthalten, da niemand Ihre Webanwendung verwenden muss, wenn er sich merken muss, dass die zu besuchende URL https://example.com/index.34def12.html lautet. Was können Sie also für diese URLs tun?

HTTP-Caching allein ist nicht leistungsstark genug, um das Netzwerk vollständig zu umgehen. Aber keine Sorge, bald erfahren Sie mehr über Service Worker, die zusätzliche Unterstützung bieten. Es gibt jedoch einige Schritte, mit denen Sie dafür sorgen können, dass Netzwerkanfragen so schnell und effizient wie möglich ausgeführt werden.

Mit den folgenden Cache-Control-Werten können Sie präzise festlegen, wo und wie nicht versionierte URLs im Cache gespeichert werden:

  • no-cache weist den Browser an, jedes Mal eine neue Validierung mit dem Server durchzuführen, bevor eine im Cache gespeicherte Version der URL verwendet wird.
  • no-store weist den Browser und andere Zwischencaches (z. B. CDNs) an, nie eine Version der Datei zu speichern.
  • private: Browser können die Datei im Cache speichern, Zwischen-Caches jedoch nicht.
  • public: Die Antwort kann von jedem Cache gespeichert werden.

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

Es kann auch helfen, entweder ETag oder Last-Modified festzulegen. Wie unter Antwortheader erwähnt, dienen ETag und Last-Modified beide demselben Zweck: Es wird ermittelt, ob der Browser eine im Cache gespeicherte Datei, die abgelaufen ist, noch einmal herunterladen muss. Wir empfehlen die Verwendung von ETag, da dies genauer ist.

ETag-Beispiel

Angenommen, seit dem ersten Abruf sind 120 Sekunden vergangen und der Browser hat eine neue Anfrage für dieselbe Ressource initiiert. Zuerst prüft der Browser den HTTP-Cache und findet die vorherige Antwort. Der Browser kann die vorherige Antwort leider nicht verwenden, da sie abgelaufen ist. An dieser Stelle kann der Browser eine neue Anfrage senden und die neue vollständige Antwort abrufen. Dies ist jedoch ineffizient, denn wenn die Ressource nicht geändert wurde, gibt es keinen Grund, die Informationen, die sich bereits im Cache befinden, noch einmal herunterzuladen.
Dies ist das Problem, das mit ETag-Validierungstokens gelöst werden soll. Der Server generiert ein beliebiges Token und gibt es zurück. Dies ist in der Regel ein Hash oder ein anderer Fingerabdruck des Inhalts der Datei. Der Browser muss nicht wissen, wie der Fingerabdruck generiert wird. Er muss ihn nur bei der nächsten Anfrage an den Server senden. Wenn der Fingerabdruck immer noch derselbe ist, hat sich die Ressource nicht geändert und der Browser kann den Download überspringen.

Wenn Sie ETag oder Last-Modified festlegen, wird die Revalidierungsanfrage erheblich effizienter, da die unter Anfrageheader genannten Anfrageheader If-Modified-Since oder If-None-Match ausgelöst werden können.

Wenn ein ordnungsgemäß konfigurierter Webserver diese eingehenden Anfrageheader sieht, kann er prüfen, ob die Version der Ressource, die sich bereits im HTTP-Cache des Browsers befindet, mit der neuesten Version auf dem Webserver übereinstimmt. Bei einer Übereinstimmung kann der Server mit der HTTP-Antwort 304 Not Modified antworten. Dies entspricht „Hey, verwende weiter das, was du bereits hast!“ Beim Senden dieses Antworttyps müssen nur sehr wenige Daten übertragen werden, sodass dies in der Regel viel schneller geht, als eine Kopie der tatsächlich angeforderten Ressource zurückzusenden.

Ein Diagramm mit einem Client, der eine Ressource anfordert, und der Server, der mit einem 304-Header antwortet.
Der Browser fordert /file vom Server an und fügt den Header If-None-Match ein, um den Server anzuweisen, die vollständige Datei nur dann 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 Werte überein und der Server gibt eine 304 Not Modified-Antwort mit einer Anleitung zurück, wie lange die Datei im Cache gespeichert werden soll (Cache-Control: max-age=120).

Zusammenfassung

Der HTTP-Cache ist eine effektive Möglichkeit, die Lastleistung zu verbessern, da er unnötige Netzwerkanfragen reduziert. Es wird von allen Browsern unterstützt und ist im Handumdrehen eingerichtet.

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

  • Cache-Control: no-cache für Ressourcen, die vor jeder Verwendung mit dem Server neu validiert werden sollen.
  • Cache-Control: no-store für Ressourcen, die nie 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 über die Grundlagen der Verwendung des Cache-Control-Headers hinausgehen möchten, lesen Sie Jake Archibalds Leitfaden Caching Best Practices und Max-age Gotchas.

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

Anhang: Weitere Tipps

Wenn Sie mehr Zeit haben, finden Sie hier weitere Möglichkeiten, die Nutzung des HTTP-Cache zu optimieren:

  • Verwenden Sie konsistente URLs. Wenn Sie dieselben Inhalte unter verschiedenen URLs bereitstellen, ruft der Browser diese Inhalte mehrmals ab und speichert sie.
  • Minimieren Sie die Abwanderung. Wenn ein Teil einer Ressource (z. B. eine CSS-Datei) häufig aktualisiert wird, der Rest der Datei jedoch nicht (wie bei Bibliothekscode), sollten Sie den häufig aktualisierenden Code in eine separate Datei aufteilen und eine kurze Caching-Strategie für den häufig aktualisierenden Code und eine Strategie für eine lange Caching-Dauer für den Code verwenden, der sich nicht oft ändert.
  • Wenn ein gewisser Grad an Veralterung in Ihrer Cache-Control-Richtlinie akzeptabel ist, sollten Sie die neue stale-while-revalidate-Richtlinie in Betracht ziehen .

Anhang: Flussdiagramm für Cache-Control

Flussdiagramm
Der Entscheidungsprozess für das Festlegen der Cache-Control-Header.

Anhang: Cache-Control Beispiele

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