Unnötige Netzwerkanfragen mit dem HTTP-Cache vermeiden

Das Abrufen von Ressourcen über das Netzwerk ist langsam und teuer:

  • Bei großen Antworten sind viele Anfragen zwischen dem Browser und dem Server erforderlich.
  • Ihre Seite wird erst geladen, wenn alle kritischen Ressourcen vollständig heruntergeladen wurden.
  • Wenn eine Person mit einem begrenzten mobilen Datentarif auf Ihre Website zugreift, ist jede unnötige Netzwerkanfrage eine Geldverschwendung.

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

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

Browserkompatibilität

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

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 vom Browser gestellten HTTP-Anfragen werden zuerst an den Browser-Cache weitergeleitet, um zu prüfen, ob eine gültige im Cache gespeicherte Antwort vorhanden ist, die zur Ausführung der Anfrage verwendet werden kann. Wenn es eine Übereinstimmung gibt, wird die Antwort aus dem Cache gelesen, wodurch sowohl die Netzwerklatenz als auch die Datenkosten beseitigt werden, die für die Übertragung anfallen.

Das Verhalten des HTTP-Cache wird durch eine Kombination aus Anfrageheadern und Antwortheadern gesteuert. Im Idealfall haben Sie die Kontrolle über den Code für Ihre Webanwendung (der die Anfrage-Header bestimmt) als auch über die Konfiguration Ihres Webservers (wodurch die Antwort-Header bestimmt werden).

Eine detailliertere konzeptionelle Übersicht finden Sie im Artikel HTTP-Caching von MDN.

Anfrageheader: (normalerweise) die Standardeinstellungen beibehalten

Es gibt eine Reihe wichtiger Header, die in den ausgehenden Anfragen Ihrer Webanwendung enthalten sein sollten, aber der Browser übernimmt fast immer diese Einstellung für Sie, wenn er Anfragen stellt. Anfrageheader, die die Prüfung auf Aktualität beeinflussen, wie If-None-Match und If-Modified-Since, basieren darauf, wie der Browser die aktuellen Werte im HTTP-Cache versteht.

Das ist eine gute Nachricht – es bedeutet, dass du weiterhin Tags wie <img src="my-image.png"> in deinen HTML-Code einfügen kannst und der Browser das HTTP-Caching automatisch und 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 spielen eine Rolle für das effektive 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 ein kleines Token (in der Regel ein Hash des Dateiinhalts) an den Server gesendet werden, um zu prüfen, ob sich die Datei geändert hat. Wenn der Server dasselbe Token zurückgibt, ist die Datei dieselbe und muss nicht noch einmal heruntergeladen werden.
  • Last-Modified: Dieser Header hat denselben Zweck wie ETag, bestimmt im Gegensatz zur inhaltsbasierten Strategie von ETag aber anhand einer zeitbasierten Strategie, ob eine Ressource geändert wurde.

Einige Webserver unterstützen die standardmäßige Festlegung dieser Header, während bei anderen die Header vollständig weggelassen werden, sofern Sie sie nicht ausdrücklich konfigurieren. Die spezifischen Details der Anleitung zum Konfigurieren von Headern variieren je nach verwendetem Webserver stark. Sie sollten die Dokumentation Ihres Servers lesen, um möglichst genaue Informationen zu erhalten.

Im Folgenden finden Sie Anweisungen zur Konfiguration gängiger Webserver, um Ihnen die Suche zu ersparen:

Wird der Antwortheader Cache-Control weggelassen, wird das HTTP-Caching nicht deaktiviert. Stattdessen können Browser effektiv schätzen, welches Caching-Verhalten für einen bestimmten Inhaltstyp am sinnvollsten ist. Wahrscheinlich möchten Sie mehr Kontrolle als das bietet. Nehmen Sie sich daher die Zeit, 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 berücksichtigen sollten.

Langlebiges Caching für versionierte URLs

Wie versionierte URLs Ihre Caching-Strategie unterstützen können
Versionierte URLs werden empfohlen, da sie das Entwerten von im Cache gespeicherten Antworten erleichtern.

Angenommen, Ihr Server weist Browser an, eine CSS-Datei für ein Jahr im Cache zu speichern (Cache-Control: max-age=31536000), aber Ihr Designer hat gerade ein Notfallupdate durchgeführt, das Sie sofort bereitstellen müssen. Wie benachrichtigen Sie Browser darüber, die „veraltete“ im Cache gespeicherte 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 so lange verwendet, bis sie nicht mehr aktuell ist, wie von max-age oder expires festgelegt, oder bis sie aus einem anderen Grund aus dem Cache entfernt wird, z. B. indem der Nutzer den Browser-Cache leert. Dies kann dazu führen, dass verschiedene Nutzer beim Erstellen der Seite verschiedene Versionen der Datei verwenden: Nutzer, die gerade die Ressource abgerufen haben, verwenden die neue Version, während Nutzer, die eine frühere (aber weiterhin gültige) Kopie im Cache gespeichert haben, eine ältere Version der Antwort verwenden.

Wie erhalte ich das Beste aus beiden Welten: clientseitiges Caching und schnelle Updates? Sie ändern die URL der Ressource und zwingen den Nutzer zum Herunterladen der neuen Antwort, wenn sich der Inhalt ändert. In der Regel betten Sie dazu einen Fingerabdruck der Datei oder eine Versionsnummer in den Dateinamen ein, z. B. style.x234dff.css.

Wenn du auf Anfragen für URLs antwortest, die fingerprint- oder Versionsinformationen enthalten und deren Inhalte nie geändert werden sollen, füge deinen Antworten Cache-Control: max-age=31536000 hinzu.

Wenn Sie diesen Wert festlegen, weiß der Browser, dass er, wenn er im nächsten Jahr (31.536.000 Sekunden; der maximal unterstützte Wert) die gleiche URL laden muss, sofort den Wert im HTTP-Cache verwenden kann, ohne dass eine Netzwerkanfrage an Ihren Webserver gestellt werden muss. Das ist großartig – Sie profitieren sofort von der Zuverlässigkeit und Geschwindigkeit, die sich aus dem Wegfall des Netzwerks ergibt.

Build-Tools wie Webpack können die Zuweisung von Hash-Fingerabdrücken zu deinen Asset-URLs automatisieren.

Erneute Validierung des Servers für nicht versionierte URLs

Leider sind nicht alle URLs, die Sie laden, versioniert. Möglicherweise können Sie vor der Bereitstellung Ihrer Webanwendung keinen Build-Schritt einfügen und somit Ihren Asset-URLs keine Hashes hinzufügen. Außerdem benötigt jede Webanwendung HTML-Dateien. Diese Dateien enthalten (fast!) niemals Versionsinformationen, da niemand Ihre Webanwendung verwendet, wenn er sich merken muss, dass die aufgerufene URL https://example.com/index.34def12.html ist. Was können Sie also mit diesen URLs tun?

Dies ist ein Szenario, in dem du deine Niederlage zugeben musst. HTTP-Caching allein ist nicht leistungsstark genug, um das Netzwerk vollständig zu umgehen. (Keine Sorge, bald werden Sie mehr über Service Worker erfahren, die uns die nötige Unterstützung bieten, um den Kampf zu Ihren Gunsten zurückzuschlagen.) Sie können jedoch einige Maßnahmen ergreifen, um dafür zu sorgen, dass Netzwerkanfragen so schnell und effizient wie möglich ausgeführt werden.

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

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

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

Es kann auch hilfreich sein, entweder ETag oder Last-Modified festzulegen. Wie unter Antwortheader erwähnt, dienen ETag und Last-Modified beide denselben Zweck: Sie sollen ermitteln, ob der Browser eine abgelaufene im Cache gespeicherte Datei noch einmal herunterladen muss. Wir empfehlen die Verwendung von ETag, da diese Funktion 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 nicht verwenden, da sie jetzt abgelaufen ist. An dieser Stelle könnte der Browser eine neue Anfrage senden und die neue vollständige Antwort abrufen. Dies ist jedoch ineffizient, denn wenn sich die Ressource nicht geändert hat, gibt es keinen Grund, die Informationen herunterzuladen, die sich bereits im Cache befinden.

Dies ist das Problem, mit dem Validierungstokens, wie im ETag-Header angegeben, gelöst werden sollen. Der Server generiert ein beliebiges Token und gibt es zurück. Dies ist normalerweise ein Hash oder ein anderer Fingerabdruck des Dateiinhalts. Der Browser muss nicht wissen, wie der Fingerabdruck generiert wird, sondern ihn nur bei der nächsten Anfrage an den Server senden. Wenn der Fingerabdruck weiterhin identisch ist, hat sich die Ressource nicht geändert und der Browser kann den Download überspringen.

Wenn Sie ETag oder Last-Modified festlegen, wird die erneute Validierungsanfrage viel effizienter, da sie die Anfrageheader If-Modified-Since oder If-None-Match auslösen kann, die unter Anfrageheader erwähnt werden.

Wenn ein ordnungsgemäß konfigurierter Webserver diese eingehenden Anfrage-Header erkennt, kann er überprüfen, ob die Version der Ressource, die sich bereits im HTTP-Cache des Browsers befindet, mit der neuesten Version auf dem Webserver übereinstimmt. Wenn es eine Übereinstimmung gibt, kann der Server mit einer HTTP-Antwort vom Typ 304 Not Modified antworten. Bei dieser Art von Antwort müssen nur sehr wenige Daten übertragen werden, sodass es normalerweise viel schneller geht, als eine Kopie der tatsächlich angeforderten Ressource zurückzusenden.

Visualisierung eines Clients, der eine Ressource anfordert, und der Server, der mit einem 304-Header antwortet.
Der Browser fordert vom Server /file an und fügt den Header If-None-Match ein, um den Server anzuweisen, nur dann 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 stimmten die beiden Werte überein, sodass der Server eine 304 Not Modified-Antwort mit Anweisungen dazu zurückgibt, wie lange die Datei noch im Cache gespeichert werden soll (Cache-Control: max-age=120).

Zusammenfassung

Der HTTP-Cache ist eine effektive Methode zur Verbesserung der Ladeleistung, da er unnötige Netzwerkanfragen reduziert. Die Funktion wird von allen Browsern unterstützt und ist schnell 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 sollten.
  • Cache-Control: no-store für Ressourcen, die niemals im Cache gespeichert werden sollen.
  • Cache-Control: max-age=31536000 für versionierte Ressourcen.

Außerdem können Sie mit dem Header ETag oder Last-Modified abgelaufene Cache-Ressourcen effizienter neu validieren.

Weitere Informationen

Wenn du mehr als die Grundlagen der Verwendung des Cache-Control-Headers erfahren möchtest, findest du im Leitfaden von Jake Archibald Best Practices für Caching und max-age-Gothchas weitere Informationen.

Unter Cache optimal nutzen erfahren Sie, wie Sie die Cache-Nutzung für wiederkehrende Besucher optimieren können.

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 denselben Inhalt unter verschiedenen URLs bereitstellen, wird dieser Inhalt mehrmals abgerufen und gespeichert.
  • Abwanderung minimieren Wenn ein Teil einer Ressource (z. B. eine CSS-Datei) häufig aktualisiert wird, der Rest der Datei jedoch nicht (z. B. Bibliothekscode), sollten Sie den häufig aktualisierten Code in eine separate Datei aufteilen und eine Caching-Strategie mit kurzer Dauer für den Code mit kurzer Dauer und eine Strategie mit langer Caching-Dauer für den Code verwenden, der sich nicht häufig ändert.
  • Falls die Richtlinie „Cache-Control“ ein gewisses Maß an Veralterung enthält, sehen Sie sich die neue stale-while-revalidate-Richtlinie an.

Anhang: Flussdiagramm für Cache-Control

Flussdiagramm
Der Entscheidungsprozess zum Festlegen Ihrer Cache-Control-Header.

Anhang: Cache-Control Beispiele

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