Finde deinen Cache ❤️

Nutzer, die Ihre Website ein zweites Mal aufrufen, verwenden ihren HTTP-Cache. Achten Sie daher darauf, dass er gut funktioniert.

Dieser Beitrag ist eine Ergänzung zum Video Love your cache, das Teil der Extended Content beim Chrome Dev Summit 2020 ist. Sehen Sie sich das Video an:

Wenn Nutzer Ihre Website ein zweites Mal laden, verwendet ihr Browser Ressourcen aus dem HTTP-Cache, um das Laden zu beschleunigen. Die Standards für das Caching im Web stammen jedoch aus dem Jahr 1999 und sind ziemlich allgemein gehalten. Es ist daher nicht immer ganz einfach zu bestimmen, ob eine Datei wie CSS oder ein Bild noch einmal aus dem Netzwerk abgerufen oder aus dem Cache geladen werden soll.

In diesem Beitrag stelle ich einen sinnvollen, modernen Standard für das Caching vor, bei dem überhaupt kein Caching erfolgt. Das ist aber nur die Standardeinstellung und es ist natürlich etwas komplizierter als nur „deaktivieren“. Am besten gleich weiterlesen!

Ziele

Wenn eine Website zum zweiten Mal geladen wird, haben Sie zwei Ziele:

  1. Sorgen Sie dafür, dass Ihre Nutzer die aktuelle Version erhalten. Wenn Sie etwas geändert haben, sollte sich das schnell widerspiegeln.
  2. Führe Schritt 1 aus und rufe dabei so wenig Daten wie möglich aus dem Netzwerk ab.

Im weitesten Sinne möchten Sie nur die kleinste Änderung an Ihre Clients senden, wenn sie Ihre Website neu laden. Außerdem ist es schwierig, Ihre Website so zu strukturieren, dass Änderungen möglichst effizient verteilt werden (mehr dazu unten und im Video).

Sie haben aber auch andere Möglichkeiten, wenn Sie das Caching in Betracht ziehen. Vielleicht haben Sie sich entschieden, dass der HTTP-Cache des Browsers eines Nutzers Ihre Website für längere Zeit speichern soll, sodass überhaupt keine Netzwerkanfragen erforderlich sind, um sie bereitzustellen. Oder Sie haben einen Service Worker erstellt, der eine Website vollständig offline bereitstellt, bevor er prüft, ob sie auf dem neuesten Stand ist. Dies ist eine extreme Option, die für viele Web-Apps, die in erster Linie offline funktionieren, gültig ist und verwendet wird. Das Web muss jedoch nicht nur auf Cache oder nur auf Netzwerk beschränkt sein.

Hintergrund

Als Webentwickler sind wir alle an die Idee eines „veralteten Cache“ gewöhnt. Wir wissen aber fast instinktiv, welche Tools zur Lösung dieses Problems zur Verfügung stehen: Wir können einen „Hard Refresh“ durchführen, ein Inkognitofenster öffnen oder eine Kombination der Entwicklertools unseres Browsers verwenden, um die Daten einer Website zu löschen.

Normale Internetnutzer haben diese Möglichkeit nicht. Wir haben zwar einige Kernziele, um sicherzustellen, dass unsere Nutzer eine tolle Zeit mit ihrem zweiten Ladevorgang haben, aber es ist auch sehr wichtig, dass sie keine schlechte Zeit haben oder stecken bleiben. (Im Video erzähle ich, wie wir die Website web.dev/live fast nicht zum Laufen gebracht hätten.)

Ein häufiger Grund für einen „veralteten Cache“ ist der Standard für das Caching aus dem Jahr 1999. Sie basiert auf dem Last-Modified-Header:

Diagramm, das zeigt, wie lange verschiedene Assets im Browser eines Nutzers zwischengespeichert werden
Assets, die zu unterschiedlichen Zeiten generiert wurden (grau), werden unterschiedlich lange im Cache gespeichert. Bei einem zweiten Laden kann es also zu einer Kombination aus Assets aus dem Cache und neuen Assets kommen.

Jede Datei, die Sie laden, wird zusätzlich 10% ihrer aktuellen Lebensdauer gespeichert, wie sie von Ihrem Browser gesehen wird. Wenn index.html beispielsweise vor einem Monat erstellt wurde, wird es noch etwa drei Tage lang im Cache Ihres Browsers gespeichert.

Das war damals eine gut gemeinte Idee, aber angesichts der eng integrierten Natur heutiger Websites kann es durch dieses Standardverhalten dazu kommen, dass ein Nutzer Dateien für verschiedene Versionen Ihrer Website hat (z.B. den JS-Code aus der Version vom Dienstag und den CSS-Code aus der Version vom Freitag), nur weil diese Dateien nicht genau zur selben Zeit aktualisiert wurden.

Der gut beleuchtete Weg

Ein moderner Standard für das Caching besteht darin, überhaupt kein Caching zu verwenden und CDNs zu nutzen, um Ihre Inhalte in die Nähe Ihrer Nutzer zu bringen. Jedes Mal, wenn ein Nutzer Ihre Website lädt, wird das Netzwerk aufgerufen, um zu prüfen, ob es auf dem neuesten Stand ist. Diese Anfrage hat eine niedrige Latenz, da sie von einem CDN bereitgestellt wird, das sich geografisch in der Nähe des jeweiligen Endnutzers befindet.

Sie können Ihren Webhost so konfigurieren, dass er auf Webanfragen mit diesem Header antwortet:

Cache-Control: max-age=0,must-revalidate,public

Das bedeutet, dass die Datei überhaupt nicht gültig ist und Sie sie über das Netzwerk validieren müssen, bevor Sie sie wieder verwenden können. Andernfalls wird sie nur „vorgeschlagen“.

Dieser Validierungsprozess ist in Bezug auf die übertragenen Bytes relativ günstig – wenn sich eine große Bilddatei nicht geändert hat, erhält Ihr Browser eine kleine 304-Antwort. Er kostet jedoch Latenz, da ein Nutzer trotzdem auf das Netzwerk zugreifen muss, um dies herauszufinden. Das ist der größte Nachteil dieses Ansatzes. Das kann für Nutzer mit schnellen Verbindungen in Industrieländern und mit einer guten Abdeckung durch das ausgewählte CDN sehr gut funktionieren, aber nicht für Nutzer mit langsameren Mobilfunkverbindungen oder einer schlechten Infrastruktur.

Unabhängig davon ist dies ein moderner Ansatz, der standardmäßig in einem beliebten CDN, Netlify, verwendet wird, aber in fast jedem CDN konfiguriert werden kann. Für Firebase Hosting können Sie diesen Header im Hosting-Abschnitt Ihrer firebase.json-Datei einfügen:

"headers": [
  // Be sure to put this last, to not override other headers
  {
    "source": "**",
    "headers": [ {
      "key": "Cache-Control",
      "value": "max-age=0,must-revalidate,public"
    }
  }
]

Ich empfehle diese Einstellung zwar weiterhin als sinnvolle Standardeinstellung, aber es ist eben nur die Standardeinstellung. Im Folgenden erfahren Sie, wie Sie eingreifen und die Standardeinstellungen aktualisieren können.

URLs mit Fingerabdruck

Wenn Sie einen Hash des Dateiinhalts in den Namen von Assets, Bildern usw. einfügen, die auf Ihrer Website bereitgestellt werden, können Sie dafür sorgen, dass diese Dateien immer eindeutige Inhalte haben. Das führt beispielsweise zu Dateinamen wie sitecode.af12de.js. Wenn Ihr Server auf Anfragen für diese Dateien antwortet, können Sie die Browser Ihrer Endnutzer sicher anweisen, sie für einen langen Zeitraum im Cache zu speichern. Konfigurieren Sie dazu diesen Header:

Cache-Control: max-age=31536000,immutable

Dieser Wert entspricht einem Jahr in Sekunden. Gemäß der Spezifikation entspricht dies effektiv „für immer“.

Wichtig: Erstellen Sie diese Hashes nicht manuell, da dies zu viel manuelle Arbeit erfordert. Dabei können Sie Tools wie Webpack oder Rollup verwenden. Weitere Informationen finden Sie im Tooling Report.

Nicht nur JavaScript kann von Fingerprint-URLs profitieren. Auch Assets wie Symbole, CSS und andere unveränderliche Datendateien können so benannt werden. Im Video oben erfahren Sie mehr zum Thema „Code-Splitting“. Damit können Sie weniger Code übertragen, wenn sich Ihre Website ändert.

Unabhängig davon, wie Ihre Website das Caching handhabt, sind diese Dateien mit Fingerabdruck für jede Website, die Sie erstellen, von unschätzbarem Wert. Die meisten Websites ändern sich nicht bei jeder Version.

Natürlich können wir unsere nutzerfreundlichen Seiten nicht auf diese Weise umbenennen: Die index.html-Datei in index.abcd12.html umzubenennen, ist nicht praktikabel, da Sie Nutzer nicht jedes Mal, wenn sie Ihre Website aufrufen, auffordern können, eine neue URL aufzurufen. Diese „freundlichen“ URLs können nicht umbenannt und auf diese Weise im Cache gespeichert werden, was mich zu einem möglichen Mittelweg führt.

Der Mittelweg

Beim Caching gibt es natürlich einen Mittelweg. Ich habe zwei extreme Optionen vorgestellt: Nie im Cache speichern oder Immer im Cache speichern. Es gibt eine Reihe von Dateien, die Sie möglicherweise für eine Weile im Cache speichern möchten, z. B. die oben erwähnten „freundlichen“ URLs.

Wenn Sie diese „freundlichen“ URLs und ihren HTML-Code im Cache speichern möchten, sollten Sie überlegen, welche Abhängigkeiten sie enthalten, wie diese im Cache gespeichert werden und wie sich das Speichern ihrer URLs im Cache für einen bestimmten Zeitraum auf Sie auswirken könnte. Sehen wir uns eine HTML-Seite an, die ein Bild wie dieses enthält:

<img src="/images/foo.jpeg" loading="lazy" />

Wenn Sie Ihre Website aktualisieren oder ändern, indem Sie dieses verzögert geladene Bild löschen oder ändern, sehen Nutzer, die eine im Cache gespeicherte Version Ihres HTML-Codes aufrufen, möglicherweise ein falsches oder fehlendes Bild, da sie beim erneuten Aufrufen Ihrer Website immer noch das ursprüngliche /images/foo.jpeg im Cache gespeichert haben.

Wenn Sie vorsichtig sind, hat das möglicherweise keine Auswirkungen auf Sie. Im Allgemeinen ist es jedoch wichtig, sich daran zu erinnern, dass Ihre Website, wenn sie von Ihren Endnutzern im Cache gespeichert wird, nicht mehr nur auf Ihren Servern vorhanden ist. Stattdessen ist es möglicherweise in Teilen in den Caches der Browser Ihrer Endnutzer vorhanden.

In den meisten Anleitungen zum Caching wird diese Art von Einstellung behandelt – möchten Sie eine Stunde, mehrere Stunden usw. lang cachen? Um diese Art von Cache einzurichten, verwenden Sie einen Header wie diesen (der 3.600 Sekunden oder eine Stunde lang im Cache gespeichert wird):

Cache-Control: max-age=3600,immutable,public

Ein letzter Punkt: Wenn Sie zeitnahe Inhalte erstellen, auf die Nutzer in der Regel nur einmal zugreifen, z. B. Nachrichtenartikel, sollten diese meiner Meinung nach nie im Cache gespeichert werden. Verwenden Sie in diesem Fall die oben genannte sinnvolle Standardeinstellung. Ich glaube, wir überschätzen oft den Wert des Caching im Vergleich zum Wunsch der Nutzer, immer die neuesten und besten Inhalte zu sehen, z. B. ein wichtiges Update zu einer Nachricht oder einem aktuellen Ereignis.

Nicht-HTML-Optionen

Neben HTML gibt es einige andere Optionen für Dateien, die sich in der Mitte befinden:

  • Suchen Sie generell nach Assets, die sich nicht auf andere auswirken.

    • Vermeiden Sie beispielsweise CSS, da es die Art und Weise ändert, wie Ihr HTML gerendert wird.
  • Große Bilder, die in aktuellen Artikeln verwendet werden

    • Ihre Nutzer werden einen einzelnen Artikel wahrscheinlich nicht mehr als ein paar Mal aufrufen. Cachen Sie Fotos oder Hero-Bilder also nicht für immer und verschwenden Sie keinen Speicherplatz.
  • Ein Asset, das etwas darstellt, das selbst eine Lebensdauer hat

    • JSON-Daten zum Wetter werden möglicherweise nur stündlich veröffentlicht. Sie können das vorherige Ergebnis also eine Stunde lang im Cache speichern, da es sich in Ihrem Fenster nicht ändert.
    • Builds eines Open-Source-Projekts können ratenbegrenzt sein. Cachen Sie daher ein Build-Statusbild, bis sich der Status möglicherweise ändert.

Zusammenfassung

Wenn Nutzer Ihre Website ein zweites Mal aufrufen, haben Sie bereits ihr Vertrauen gewonnen. Sie möchten zurückkehren und mehr von Ihrem Angebot sehen. An diesem Punkt geht es nicht immer nur darum, die Ladezeit zu verkürzen. Sie haben eine Reihe von Optionen, um dafür zu sorgen, dass Ihr Browser nur die Arbeit erledigt, die erforderlich ist, um sowohl eine schnelle als auch eine aktuelle Nutzererfahrung zu bieten.

Caching ist kein neues Konzept im Web, aber vielleicht ist ein sinnvoller Standard erforderlich. Erwägen Sie, einen solchen zu verwenden und bessere Caching-Strategien zu aktivieren, wenn Sie sie benötigen. Vielen Dank, dass Sie sich die Zeit zum Lesen dieser E-Mail genommen haben.

Weitere Informationen

Einen allgemeinen Leitfaden zum HTTP-Cache finden Sie unter Unnötige Netzwerkanfragen mit dem HTTP-Cache verhindern.