Traditionelle prefetching-Techniken durch Service Worker ergänzen
Die Ausführung einer Aufgabe auf einer Website umfasst in der Regel mehrere Schritte. Der Kauf eines Produkts auf einer E-Commerce-Website kann beispielsweise die Suche nach einem Produkt, die Auswahl eines Artikels aus der Liste der Ergebnisse, das Hinzufügen des Artikels zum Einkaufswagen und den Abschluss des Vorgangs durch den Bezahlvorgang umfassen.
Technisch gesehen bedeutet das Wechseln zwischen verschiedenen Seiten, eine Navigationsanfrage zu stellen. Als Faustregel gilt: Verwenden Sie keine langlebigen Cache-Control
-Header, um die HTML-Antwort für eine Navigationsanfrage im Cache zu speichern. Sie sollten normalerweise über das Netzwerk mit Cache-Control: no-cache
zufrieden sein, um sicherzustellen, dass der HTML-Code zusammen mit der Kette nachfolgender Netzwerkanfragen (in angemessenem Maße) aktuell ist.
Wenn der Nutzer jedes Mal das Netzwerk aufrufen muss, wenn er eine neue Seite aufruft, kann das leider dazu führen, dass jede Navigation langsam ist. Zumindest bedeutet das, dass sie nicht zuverlässig schnell ist.
Wenn Sie die Aktion des Nutzers vorhersehen können, können Sie diese Seiten und Assets vorab anfordern und für kurze Zeit im Cache speichern, bis der Nutzer auf diese Links klickt. Diese Methode wird als Prefetching bezeichnet. Sie wird in der Regel durch Einfügen von <link rel="prefetch">
-Tags auf Seiten implementiert, die die zu vorab ladende Ressource angeben.
In diesem Leitfaden erfahren Sie, wie Dienstprogramme als Ergänzung zu herkömmlichen Prefetching-Techniken verwendet werden können.
Produktionsfälle
MercadoLibre ist die größte E-Commerce-Website in Lateinamerika. Um die Navigation zu beschleunigen, werden <link rel="prefetch">
-Tags in einigen Teilen des Ablaufs dynamisch eingefügt. Auf Eintragsseiten wird beispielsweise die nächste Ergebnisseite abgerufen, sobald der Nutzer ans Ende des Eintrags scrollt:
Vorab abgerufene Dateien werden mit der Priorität „Niedrigste“ angefordert und je nachdem, ob die Ressource im Cache gespeichert werden kann oder nicht, für eine Zeitspanne, die je nach Browser variiert, im HTTP-Cache oder im Speichercache gespeichert. Ab Chrome 85 beträgt dieser Wert beispielsweise 5 Minuten. Ressourcen werden fünf Minuten lang beibehalten, danach gelten die normalen Cache-Control
-Regeln für die Ressource.
Mit dem Dienstworker-Caching können Sie die Lebensdauer von Ressourcen für die Vorab-Datenübertragung über das Fünf-Minuten-Zeitfenster hinaus verlängern.
Das italienische Sportportal Virgilio Sport verwendet beispielsweise Dienstworker, um die beliebtesten Beiträge auf der Startseite vorab zu laden. Außerdem wird die Network Information API verwendet, um das Vorabladen für Nutzer mit einer 2G-Verbindung zu vermeiden.
Daher hat Virgilio Sport über drei Wochen hinweg beobachtete, dass die Ladezeiten für die Navigation zu Artikeln um 78% stiegen und die Anzahl der Artikelimpressionen um 45% stieg.
Precaching mit Workbox implementieren
Im folgenden Abschnitt verwenden wir Workbox, um zu zeigen, wie verschiedene Caching-Techniken im Service Worker implementiert werden. Diese können als Ergänzung zu <link rel="prefetch">
oder sogar als Ersatz verwendet werden, indem diese Aufgabe vollständig an den Service Worker delegiert wird.
1. Statische Seiten und Seitenunterressourcen vorab im Cache speichern
Beim Vorab-Caching kann der Dienst-Worker Dateien während der Installation im Cache speichern.
In den folgenden Fällen wird das Precaching verwendet, um ein ähnliches Ziel wie das Prefetching zu erreichen: die Navigation zu beschleunigen.
Statische Seiten vorab im Cache speichern
Bei Seiten, die zur Buildzeit generiert werden (z. B. about.html
, contact.html
), oder bei vollständig statischen Websites können die Dokumente der Website einfach der Pre-Cache-Liste hinzugefügt werden, damit sie bei jedem Zugriff des Nutzers bereits im Cache verfügbar sind:
workbox.precaching.precacheAndRoute([
{url: '/about.html', revision: 'abcd1234'},
// ... other entries ...
]);
Untergeordnete Ressourcen der Seite vorab laden
Das Precaching statischer Assets, die in den verschiedenen Bereichen der Website verwendet werden können (z. B. JavaScript, CSS), ist eine allgemeine Best Practice und kann in Prefetching-Szenarien einen zusätzlichen Schub geben.
Um die Navigation auf einer E-Commerce-Website zu beschleunigen, können Sie <link rel="prefetch">
-Tags auf Eintragsseiten verwenden, um Produktdetailseiten für die ersten Produkte einer Eintragsseite vorab zu laden. Wenn Sie die untergeordneten Ressourcen der Produktseite bereits im Cache gespeichert haben, kann die Navigation noch schneller erfolgen.
So implementieren Sie diese Funktion:
- Fügen Sie der Seite ein
<link rel="prefetch">
-Tag hinzu:
<link rel="prefetch" href="/phones/smartphone-5x.html" as="document">
- Fügen Sie der Precache-Liste im Service Worker die Unterressourcen der Seite hinzu:
workbox.precaching.precacheAndRoute([
'/styles/product-page.ac29.css',
// ... other entries ...
]);
2. Lebensdauer von Ressourcen für die Vorab-Datenübertragung verlängern
Wie bereits erwähnt, ruft <link rel="prefetch">
Ressourcen ab und speichert sie für einen begrenzten Zeitraum im HTTP-Cache. Danach gelten die Cache-Control
-Regeln für eine Ressource. Ab Chrome 85 beträgt dieser Wert 5 Minuten.
Mit Service Workern können Sie die Lebensdauer der Prefetch-Seiten verlängern und gleichzeitig den zusätzlichen Vorteil bieten, dass Sie diese Ressourcen für die Offlinenutzung verfügbar machen.
Im vorherigen Beispiel könnte <link rel="prefetch">
, das zum Vorabladen einer Produktseite verwendet wird, durch eine Workbox-Laufzeit-Caching-Strategie ergänzt werden.
So implementieren Sie das:
- Fügen Sie der Seite ein
<link rel="prefetch">
-Tag hinzu:
<link rel="prefetch" href="/phones/smartphone-5x.html" as="document">
- Implementieren Sie im Service Worker eine Laufzeit-Caching-Strategie für diese Arten von Anfragen:
new workbox.strategies.StaleWhileRevalidate({
cacheName: 'document-cache',
plugins: [
new workbox.expiration.Plugin({
maxAgeSeconds: 30 * 24 * 60 * 60, // 30 Days
}),
],
});
In diesem Fall haben wir uns für eine Stale-While-Revalidate-Strategie entschieden. Bei dieser Strategie können Seiten parallel aus dem Cache und dem Netzwerk angefordert werden. Die Antwort stammt aus dem Cache, sofern verfügbar, andernfalls aus dem Netzwerk. Der Cache wird bei jeder erfolgreichen Anfrage immer mit der Netzwerkantwort aktualisiert.
3. Prefetching an den Service Worker delegieren
In den meisten Fällen ist die Verwendung von <link rel="prefetch">
der beste Ansatz. Das Tag ist ein Ressourcenhinweis, der das Vorabladen so effizient wie möglich macht.
In einigen Fällen kann es jedoch besser sein, diese Aufgabe vollständig an den Service Worker zu delegieren.
Wenn Sie beispielsweise die ersten Produkte auf einer clientseitig gerenderten Seite mit Produktinformationen vorab abrufen möchten, müssen Sie möglicherweise mehrere <link rel="prefetch">
-Tags basierend auf einer API-Antwort dynamisch in die Seite einfügen. Dies kann den Hauptthread der Seite vorübergehend belasten und die Implementierung erschweren.
Verwenden Sie in solchen Fällen eine „Kommunikationsstrategie für Seiten und Dienst-Worker“, um die Aufgabe des Vorabladens vollständig an den Dienst-Worker zu delegieren. Diese Art der Kommunikation kann mit worker.postMessage() erreicht werden:
Das Workbox Window-Paket vereinfacht diese Art der Kommunikation, indem viele Details des zugrunde liegenden Aufrufs abstrahiert werden.
Das Vorabladen mit dem Workbox-Fenster kann so implementiert werden:
- Auf der Seite: Rufen Sie den Service Worker auf und übergeben Sie ihm die Art der Nachricht und die Liste der URLs, die vorab abgerufen werden sollen:
const wb = new Workbox('/sw.js');
wb.register();
const prefetchResponse = await wb.messageSW({type: 'PREFETCH_URLS', urls: […]});
- Im Service Worker: Implementieren Sie einen Nachrichten-Handler, um für jede URL, die vorab abgerufen werden soll, eine
fetch()
-Anfrage zu senden:
addEventListener('message', (event) => {
if (event.data.type === 'PREFETCH_URLS') {
// Fetch URLs and store them in the cache
}
});