Ressourcen während der Laufzeit zwischenspeichern

Einige Assets in Ihrer Webanwendung werden möglicherweise selten verwendet, sind sehr groß oder variieren je nach Gerät des Nutzers (z. B. responsive Bilder) oder Sprache. In diesen Fällen kann das Vorab-Caching ein Anti-Muster sein und Sie sollten sich stattdessen auf das Laufzeit-Caching verlassen.

In Workbox können Sie das Laufzeit-Caching für Assets mit dem workbox-routing-Modul verarbeiten, um Routen abzugleichen, und Caching-Strategien für diese mit dem workbox-strategies-Modul verarbeiten.

Caching-Strategien

Sie können die meisten Routen für Assets mit einer der integrierten Caching-Strategien verarbeiten. Sie werden weiter oben in dieser Dokumentation ausführlich behandelt. Im Folgenden finden Sie einige Punkte, die es wert ist, noch einmal zusammengefasst zu werden:

  • Bei Veraltete Überprüfung wird für eine Anfrage eine im Cache gespeicherte Antwort verwendet, sofern sie verfügbar ist, und der Cache wird im Hintergrund mit einer Antwort des Netzwerks aktualisiert. Wenn das Asset nicht im Cache gespeichert wird, wartet es daher auf die Netzwerkantwort und verwendet diese. Dies ist eine ziemlich sichere Strategie, da die darauf basierenden Cache-Einträge regelmäßig aktualisiert werden. Der Nachteil ist, dass im Hintergrund immer ein Asset aus dem Netzwerk angefordert wird.
  • Network First versucht zuerst, eine Antwort vom Netzwerk zu erhalten. Wenn eine Antwort empfangen wird, wird diese an den Browser übergeben und in einem Cache gespeichert. Wenn die Netzwerkanfrage fehlschlägt, wird die letzte im Cache gespeicherte Antwort verwendet, um den Offlinezugriff auf das Asset zu ermöglichen.
  • Mit Cache First wird der Cache zuerst auf eine Antwort geprüft und gegebenenfalls verwendet. Befindet sich die Anfrage nicht im Cache, wird das Netzwerk verwendet und die gültige Antwort wird dem Cache hinzugefügt, bevor sie an den Browser übergeben wird.
  • Bei Nur Netzwerk wird erzwungen, dass die Antwort aus dem Netzwerk kommt.
  • Nur Cache erzwingt, dass die Antwort aus dem Cache kommt.

Du kannst diese Strategien anwenden, um Anfragen mithilfe der von workbox-routing angebotenen Methoden auszuwählen.

Caching-Strategien mit Routenabgleich anwenden

workbox-routing stellt eine registerRoute-Methode zur Verfügung, um Routen abzugleichen und mit einer Caching-Strategie zu verarbeiten. registerRoute akzeptiert ein Route-Objekt, das wiederum zwei Argumente akzeptiert:

  1. Ein String, ein regulärer Ausdruck oder ein Übereinstimmungs-Callback, um Kriterien für den Routenabgleich anzugeben.
  2. Ein Handler für die Route – in der Regel eine von workbox-strategies bereitgestellte Strategie.

Abgleich-Callbacks werden bevorzugt, um Routen abzugleichen, da sie ein Kontextobjekt bereitstellen, das das Request-Objekt, den Anfrage-URL-String, das Fetch-Ereignis und einen booleschen Wert enthält, der angibt, ob die Anfrage vom selben Ursprung stammt.

Der Handler verarbeitet dann die übereinstimmende Route. Im folgenden Beispiel wird eine neue Route erstellt, die den eingehenden Bildanfragen am selben Ursprung entspricht. Dabei wird zuerst der Cache angewendet, dann auf die Netzwerkstrategie zurückgegriffen.

// sw.js
import { registerRoute, Route } from 'workbox-routing';
import { CacheFirst } from 'workbox-strategies';

// A new route that matches same-origin image requests and handles
// them with the cache-first, falling back to network strategy:
const imageRoute = new Route(({ request, sameOrigin }) => {
  return sameOrigin && request.destination === 'image'
}, new CacheFirst());

// Register the new route
registerRoute(imageRoute);

Mehrere Caches verwenden

Mit Workbox können Sie im Cache gespeicherte Antworten mithilfe der Option cacheName, die in den gebündelten Strategien verfügbar ist, in separate Cache-Instanzen gruppieren.

Im folgenden Beispiel wird für Bilder eine Strategie des Typs „Während der Neuvalidierung“ verwendet, während für CSS- und JavaScript-Assets eine Cache-First-Fallback-Strategie verwendet wird. Die Route für jedes Asset platziert die Antworten durch Hinzufügen des Attributs cacheName in separaten Caches.

// sw.js
import { registerRoute, Route } from 'workbox-routing';
import { CacheFirst, StaleWhileRevalidate } from 'workbox-strategies';

// Handle images:
const imageRoute = new Route(({ request }) => {
  return request.destination === 'image'
}, new StaleWhileRevalidate({
  cacheName: 'images'
}));

// Handle scripts:
const scriptsRoute = new Route(({ request }) => {
  return request.destination === 'script';
}, new CacheFirst({
  cacheName: 'scripts'
}));

// Handle styles:
const stylesRoute = new Route(({ request }) => {
  return request.destination === 'style';
}, new CacheFirst({
  cacheName: 'styles'
}));

// Register routes
registerRoute(imageRoute);
registerRoute(scriptsRoute);
registerRoute(stylesRoute);
<ph type="x-smartling-placeholder">
</ph> Screenshot der Liste der Cache-Instanzen auf dem Anwendungstab der Chrome-Entwicklertools. Es werden drei verschiedene Caches angezeigt: einer mit dem Namen „scripts“, ein anderer mit dem Namen „styles“ und der letzte mit dem Namen „images“.
. Viewer für Cache-Speicher im Anwendungsbereich der Chrome-Entwicklertools Antworten für verschiedene Asset-Typen werden in separaten Caches gespeichert.

Ablaufdatum für Cache-Einträge festlegen

Achten Sie bei der Verwaltung von Service Worker-Caches auf Speicherkontingente. ExpirationPlugin vereinfacht die Cache-Wartung und wird von workbox-expiration bereitgestellt. Um sie zu verwenden, geben Sie sie in der Konfiguration einer Caching-Strategie an:

// sw.js
import { registerRoute, Route } from 'workbox-routing';
import { CacheFirst } from 'workbox-strategies';
import { ExpirationPlugin } from 'workbox-expiration';

// Evict image cache entries older thirty days:
const imageRoute = new Route(({ request }) => {
  return request.destination === 'image';
}, new CacheFirst({
  cacheName: 'images',
  plugins: [
    new ExpirationPlugin({
      maxAgeSeconds: 60 * 60 * 24 * 30,
    })
  ]
}));

// Evict the least-used script cache entries when
// the cache has more than 50 entries:
const scriptsRoute = new Route(({ request }) => {
  return request.destination === 'script';
}, new CacheFirst({
  cacheName: 'scripts',
  plugins: [
    new ExpirationPlugin({
      maxEntries: 50,
    })
  ]
}));

// Register routes
registerRoute(imageRoute);
registerRoute(scriptsRoute);
verwendet wird.

Die Einhaltung von Speicherkontingenten kann kompliziert sein. Es empfiehlt sich, Nutzer zu bedenken, die möglicherweise einem Speicherproblem ausgesetzt sind oder den Speicherplatz möglichst effizient nutzen möchten. Die ExpirationPlugin-Paare der Workbox können dabei helfen, dieses Ziel zu erreichen.

Ursprungsübergreifende Überlegungen

Die Interaktion zwischen Ihrem Service Worker und den ursprungsübergreifenden Assets unterscheidet sich erheblich von der Interaktion mit ursprungsübergreifenden Assets. Cross-Origin Resource Sharing (CORS) ist kompliziert und erstreckt sich auch auf die Handhabung ursprungsübergreifender Ressourcen in einem Service Worker.

Undurchsichtige Antworten

Wenn eine ursprungsübergreifende Anfrage im no-cors-Modus gestellt wird, kann die Antwort in einem Service Worker-Cache gespeichert und sogar direkt vom Browser verwendet werden. Der Antworttext selbst kann jedoch nicht über JavaScript gelesen werden. Dies wird als opake Antwort bezeichnet.

Undurchsichtige Antworten sind eine Sicherheitsmaßnahme, die die Prüfung eines ursprungsübergreifenden Assets verhindern soll. Sie können weiterhin Anfragen für ursprungsübergreifende Assets stellen und diese sogar im Cache speichern. Sie können lediglich den Antworttext und nicht einmal seinen Statuscode lesen.

Denken Sie daran, den CORS-Modus zu aktivieren

Selbst wenn Sie ursprungsübergreifende Assets laden, die erlaubte CORS-Header festlegen, die das Lesen von Antworten ermöglichen, kann der Text der ursprungsübergreifenden Antwort trotzdem undurchsichtig sein. Der folgende HTML-Code löst beispielsweise no-cors-Anfragen aus, die unabhängig davon, welche CORS-Header festgelegt sind, zu undurchsichtigen Antworten führen:

<link rel="stylesheet" href="https://example.com/path/to/style.css">
<img src="https://example.com/path/to/image.png">

Wenn Sie explizit eine cors-Anfrage auslösen möchten, die eine undurchsichtige Antwort zurückgibt, müssen Sie den CORS-Modus explizit aktivieren, indem Sie dem HTML-Code das Attribut crossorigin hinzufügen:

<link crossorigin="anonymous" rel="stylesheet" href="https://example.com/path/to/style.css">
<img crossorigin="anonymous" src="https://example.com/path/to/image.png">

Dies ist wichtig, wenn Routen in Ihrem Service Worker Unterressourcen, die zur Laufzeit geladen werden, im Cache speichern.

Die Workbox speichert möglicherweise keine undurchsichtigen Antworten im Cache

In der Standardeinstellung verfolgt Workbox eine vorsichtige Herangehensweise an das Caching undurchsichtiger Antworten. Da es nicht möglich ist, den Antwortcode auf undurchsichtige Antworten zu untersuchen, kann das Caching einer Fehlerantwort zu dauerhaften Fehlern führen, wenn eine Cache-First- oder Cache-Only-Strategie verwendet wird.

Wenn Sie eine intransparente Antwort in der Workbox zwischenspeichern müssen, sollten Sie dafür eine Strategie des Typs „network-first“ oder „veraltet“ verwenden. Ja. Das bedeutet, dass das Asset weiterhin jedes Mal vom Netzwerk angefordert wird, aber fehlgeschlagene Antworten nicht beibehalten und schließlich durch verwendbare Antworten ersetzt werden.

Wenn Sie eine andere Caching-Strategie verwenden und eine intransparente Antwort zurückgegeben wird, werden Sie von Workbox gewarnt, dass die Antwort im Entwicklungsmodus nicht im Cache gespeichert wurde.

Caching von undurchsichtigen Antworten erzwingen

Wenn Sie absolut sicher sind, dass Sie eine intransparente Antwort mit einer Cache-First- oder Cache-Only-Strategie im Cache speichern möchten, können Sie Workbox dies mit dem workbox-cacheable-response-Modul erzwingen:

import {Route, registerRoute} from 'workbox-routing';
import {NetworkFirst, StaleWhileRevalidate} from 'workbox-strategies';
import {CacheableResponsePlugin} from 'workbox-cacheable-response';

const cdnRoute = new Route(({url}) => {
  return url === 'https://cdn.google.com/example-script.min.js';
}, new CacheFirst({
  plugins: [
    new CacheableResponsePlugin({
      statuses: [0, 200]
    })
  ]
}))

registerRoute(cdnRoute);

Intransparente Antworten und die navigator.storage API

Um den Verlust von domainübergreifenden Informationen zu vermeiden, wird der Größe einer intransparenten Antwort zur Berechnung der Speicherkontingentlimits ein signifikantes Padding hinzugefügt. Das wirkt sich darauf aus, wie die navigator.storage API Speicherkontingente meldet.

Dieser Abstand variiert je nach Browser, aber bei Chrome beträgt die Mindestgröße, die eine einzelne undurchsichtige Antwort im Cache zum insgesamt genutzten Speicherplatz beiträgt, ungefähr 7 MB. Sie sollten dies beachten, wenn Sie ermitteln, wie viele undurchsichtige Antworten im Cache gespeichert werden sollen, da Sie Speicherkontingente viel schneller überschreiten können, als Sie es normalerweise erwarten.