Caching

Die Cache-Speicherung ist ein leistungsstarkes Tool. Dadurch sind Ihre Apps weniger von den Netzwerkbedingungen abhängig. Durch die richtige Verwendung von Caches können Sie Ihre Web-App offline verfügbar machen und Ihre Assets unter allen Netzwerkbedingungen so schnell wie möglich bereitstellen. Wie unter Assets und Daten beschrieben, können Sie die beste Strategie zum Zwischenspeichern der erforderlichen Assets festlegen. Zum Verwalten des Caches, mit dem Ihr Service Worker interagiert, verwenden Sie die Cache Storage API.

Browser Support

  • Chrome: 43.
  • Edge: 16.
  • Firefox: 41.
  • Safari: 11.1.

Source

Die Cache Storage API ist in verschiedenen Kontexten verfügbar:

  • Der Fensterkontext (der Hauptthread Ihrer PWA).
  • Der Service Worker.
  • Alle anderen Mitarbeiter, die Sie beschäftigen.

Ein Vorteil der Verwaltung Ihres Caches mit Service Workern besteht darin, dass sein Lebenszyklus nicht an das Fenster gebunden ist. Das bedeutet, dass Sie den Hauptthread nicht blockieren. Beachten Sie, dass für die Verwendung der Cache Storage API die meisten dieser Kontexte über eine TLS-Verbindung erfolgen müssen.

Was im Cache gespeichert werden soll

Die erste Frage, die Sie sich zum Caching stellen, ist wahrscheinlich, was gecacht werden soll. Es gibt keine Universallösung für diese Frage. Sie können jedoch mit allen Mindestressourcen beginnen, die zum Rendern der Benutzeroberfläche erforderlich sind.

Dazu gehören:

  • Der HTML-Code der Hauptseite (die start_url Ihrer App).
  • CSS-Stylesheets, die für die Hauptbenutzeroberfläche benötigt werden.
  • In der Benutzeroberfläche verwendete Bilder
  • JavaScript-Dateien, die zum Rendern der Benutzeroberfläche erforderlich sind.
  • Daten wie eine JSON-Datei, die zum Rendern einer einfachen Darstellung erforderlich sind.
  • Webfonts
  • In einer mehrseitigen Anwendung andere HTML-Dokumente, die schnell oder offline bereitgestellt werden sollen.

Für den Offlinezugriff verfügbar

Die Offline-Funktionalität ist zwar eine der Anforderungen für eine progressive Web-App, aber nicht jede PWA muss eine vollständige Offline-Funktionalität bieten, z. B. Cloud-Gaming-Lösungen oder Krypto-Assets-Apps. Daher ist es in Ordnung, eine einfache Benutzeroberfläche anzubieten, die Nutzer durch diese Situationen führt.

Ihre PWA sollte keine Fehlermeldung des Browsers rendern, die besagt, dass die Web-Rendering-Engine die Seite nicht laden konnte. Verwenden Sie stattdessen Ihren Service Worker, um Ihre eigenen Mitteilungen anzuzeigen und so einen allgemeinen und verwirrenden Browserfehler zu vermeiden.

Je nach den Anforderungen Ihrer PWA können Sie viele verschiedene Caching-Strategien verwenden. Daher ist es wichtig, die Cachenutzung so zu gestalten, dass sie eine schnelle und zuverlässige Nutzung ermöglicht. Wenn beispielsweise alle Assets Ihrer App schnell heruntergeladen werden, nicht viel Speicherplatz benötigen und nicht bei jeder Anfrage aktualisiert werden müssen, ist das Caching aller Assets eine sinnvolle Strategie. Wenn Sie hingegen Ressourcen haben, die die neueste Version sein müssen, sollten Sie in Erwägung ziehen, diese Assets überhaupt nicht zu cachen.

API verwenden

Mit der Cache Storage API können Sie eine Reihe von Caches in Ihrem Ursprung definieren, die jeweils durch einen von Ihnen definierten Stringnamen identifiziert werden. Auf die API wird über das caches-Objekt zugegriffen. Mit der Methode open kann ein Cache erstellt oder ein bereits erstellter Cache geöffnet werden. Die Methode „open“ gibt ein Promise für das Cache-Objekt zurück.

caches.open("pwa-assets")
.then(cache => {
  // you can download and store, delete or update resources with cache arguments
});

Assets herunterladen und speichern

Verwenden Sie die Methoden add oder addAll, um den Browser aufzufordern, die Assets herunterzuladen und zu speichern. Mit der Methode add wird eine Anfrage gestellt und eine HTTP-Antwort gespeichert. Mit addAll wird eine Gruppe von HTTP-Antworten als Transaktion auf Grundlage eines Arrays von Anfragen oder URLs gespeichert.

caches.open("pwa-assets")
.then(cache => {
  cache.add("styles.css"); // it stores only one resource
  cache.addAll(["styles.css", "app.js"]); // it stores two resources
});

Über die Cache-Speicherschnittstelle wird die gesamte Antwort gespeichert, einschließlich aller Header und des Texts. Sie können sie also später mit einer HTTP-Anfrage oder einer URL als Schlüssel abrufen. Wie das funktioniert, erfahren Sie im Kapitel zum Bereitstellen.

Wann sollte gecacht werden?

In Ihrer PWA entscheiden Sie, wann Dateien im Cache gespeichert werden sollen. Eine Möglichkeit besteht darin, beim Installieren des Service Workers so viele Assets wie möglich zu speichern. Das ist aber in der Regel nicht die beste Idee. Das Zwischenspeichern unnötiger Ressourcen verschwendet Bandbreite und Speicherplatz und kann dazu führen, dass Ihre App unbeabsichtigt veraltete Ressourcen bereitstellt.

Sie müssen nicht alle Assets auf einmal im Cache speichern. Sie können Assets während des Lebenszyklus Ihrer PWA mehrmals im Cache speichern, z. B.:

  • Bei der Installation des Service Workers.
  • Nach dem ersten Laden der Seite.
  • Wenn der Nutzer einen Abschnitt oder eine Route aufruft.
  • Wenn das Netzwerk im Leerlauf ist.

Sie können das Caching neuer Dateien im Hauptthread oder im Service Worker-Kontext anfordern.

Assets in einem Service Worker im Cache speichern

Eines der häufigsten Szenarien ist das Zwischenspeichern einer Mindestanzahl von Assets bei der Installation des Service Workers. Dazu können Sie die Cache-Speicherschnittstelle innerhalb des install-Ereignisses im Service Worker verwenden.

Da der Service Worker-Thread jederzeit beendet werden kann, können Sie den Browser anweisen, auf das addAll-Promise zu warten, um die Wahrscheinlichkeit zu erhöhen, dass alle Assets gespeichert werden und die App konsistent bleibt. Im folgenden Beispiel wird gezeigt, wie das mit der Methode waitUntil des Ereignisarguments, das im Service Worker-Ereignis-Listener empfangen wird, funktioniert.

const urlsToCache = ["/", "app.js", "styles.css", "logo.svg"];
self.addEventListener("install", event => {
   event.waitUntil(
      caches.open("pwa-assets")
      .then(cache => {
         return cache.addAll(urlsToCache);
      });
   );
});

Die waitUntil()-Methode empfängt ein Promise und fordert den Browser auf, zu warten, bis die Aufgabe im Promise abgeschlossen ist (erfüllt oder fehlgeschlagen), bevor der Service Worker-Prozess beendet wird. Möglicherweise müssen Sie Promises verketten und die add()- oder addAll()-Aufrufe zurückgeben, damit ein einzelnes Ergebnis an die waitUntil()-Methode übergeben wird.

Sie können Promises auch mit der async/await-Syntax verarbeiten. In diesem Fall müssen Sie eine asynchrone Funktion erstellen, die await aufrufen kann und die nach dem Aufruf ein Promise für waitUntil() zurückgibt, wie im folgenden Beispiel:

const urlsToCache = ["/", "app.js", "styles.css", "logo.svg"];
self.addEventListener("install", (event) => {
   let cacheUrls = async () => {
      const cache = await caches.open("pwa-assets");
      return cache.addAll(urlsToCache);
   };
   event.waitUntil(cacheUrls());
});

Domainübergreifende Anfragen und undurchsichtige Antworten

Ihre PWA kann Assets von Ihrem Ursprung und von domänenübergreifenden Quellen wie Inhalten von Drittanbieter-CDNs herunterladen und im Cache speichern. Bei einer domainübergreifenden App ähnelt die Cache-Interaktion sehr stark der bei Anfragen mit demselben Ursprung. Die Anfrage wird ausgeführt und eine Kopie der Antwort wird in Ihrem Cache gespeichert. Wie bei anderen im Cache gespeicherten Assets kann es nur im Ursprung Ihrer App verwendet werden.

Das Asset wird als undurchsichtige Antwort gespeichert. Das bedeutet, dass Ihr Code den Inhalt oder die Header dieser Antwort nicht sehen oder ändern kann. Außerdem wird die tatsächliche Größe von intransparenten Antworten in der Storage API nicht offengelegt, was sich auf Kontingente auswirkt. Einige Browser geben große Größen an, z. B. 7 MB, unabhängig davon, ob die Datei nur 1 KB groß ist.

Assets aktualisieren und löschen

Sie können Assets mit cache.put(request, response) aktualisieren und mit delete(request) löschen.

Weitere Informationen finden Sie in der Dokumentation zum Cache-Objekt.

Cache-Speicher debuggen

Viele Browser bieten die Möglichkeit, den Inhalt des Cache-Speichers auf dem Tab „Anwendung“ der Entwicklertools zu debuggen. Dort sehen Sie den Inhalt jedes Caches im aktuellen Ursprung. Weitere Informationen zu diesen Tools finden Sie im Kapitel „Tools und Debugging“.

Cache Storage-Inhalte mit den Chrome-Entwicklertools debuggen

Ressourcen