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
erfüllt werden, damit die HTML-Datei und die nachfolgenden Netzwerkanfragen (relativ) aktuell sind.
Wenn jedes Mal, wenn der Nutzer zu einer neuen Seite wechselt, das Netzwerk kontaktiert werden muss, kann die Navigation leider langsam sein. Zumindest ist sie nicht zuverlässig schnell.
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 in einigen Teilen des Navigationsflusses dynamisch <link rel="prefetch">
-Tags eingefügt. Auf Listenseiten wird beispielsweise die nächste Ergebnisseite abgerufen, sobald der Nutzer zum 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. In 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 Service Worker-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 Dienst-Worker, 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.
In den drei Wochen, in denen die Änderungen beobachtet wurden, konnte Virgilio Sport eine 78%ige Verbesserung bei den Ladezeiten für die Navigation zu Artikeln und eine 45%ige Steigerung der Anzahl der Artikelimpressionen feststellen.
Precaching mit Workbox implementieren
Im folgenden Abschnitt zeigen wir anhand von Workbox, wie Sie verschiedene Caching-Techniken im Service Worker implementieren, die als Ergänzung zu <link rel="prefetch">
oder sogar als Ersatz dafür verwendet werden können, indem Sie diese Aufgabe vollständig an den Service Worker delegieren.
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 Sie die Dokumente der Website einfach der Pre-Cache-Liste hinzufügen, 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 bei 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 die Seitenunterressourcen der Pre-Cache-Liste im Service Worker 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 eine begrenzte Zeit im HTTP-Cache. Danach werden die Cache-Control
-Regeln für eine Ressource angewendet. Ab Chrome 85 beträgt dieser Wert 5 Minuten.
Mit Service Workern können Sie die Lebensdauer der vorab geladenen Seiten verlängern und diese Ressourcen zusätzlich 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 es am besten, <link rel="prefetch">
zu verwenden. Das Tag ist ein Ressourcenhinweis, der das Vorabladen so effizient wie möglich macht.
In einigen Fällen ist es jedoch besser, diese Aufgabe vollständig an den Service Worker zu delegieren.
Beispiel: Um die ersten Produkte auf einer clientseitig gerenderten Produktlistenseite vorab zu laden, müssen möglicherweise mehrere <link rel="prefetch">
-Tags basierend auf einer API-Antwort dynamisch in die Seite eingefügt werden. 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
}
});