Navigationsanfragen verarbeiten

Mit einem Service Worker auf Navigationsanfragen reagieren, ohne im Netzwerk warten zu müssen

Navigationsanfragen sind Anfragen für HTML-Dokumente, die von Ihrem Browser gesendet werden, wenn Sie eine neue URL in die Navigationsleiste eingeben oder einem Link auf einer Seite folgen, der Sie zu einer neuen URL führt. Hier haben Service Worker ihren größten Einfluss auf die Leistung: Wenn Sie mit einem Service Worker auf Navigationsanfragen antworten, ohne auf das Netzwerk warten zu müssen, können Sie dafür sorgen, dass die Navigation zuverlässig und schnell ist, wenn das Netzwerk nicht verfügbar ist. Dies ist der einzige größte Leistungsgewinn, der durch einen Service Worker im Vergleich zum HTTP-Caching möglich ist.

Wie im Leitfaden Aus dem Netzwerk geladene Ressourcen identifizieren beschrieben, ist eine Navigationsanfrage die erste von potenziell vielen Anfragen im „Wasserfall“ des Netzwerktraffics. Der HTML-Code, den Sie über eine Navigationsanfrage laden, löst den Fluss aller anderen Anfragen für Unterressourcen wie Bilder, Skripts und Stile aus.

Innerhalb des Event-Handlers fetch eines Service Workers können Sie anhand des Attributs request.mode für FetchEvent feststellen, ob eine Anfrage eine Navigation ist. Ist sie auf 'navigate' gesetzt, ist es eine Navigationsanfrage.

Generell sollten die langlebigen Cache-Control headers nicht verwendet werden, um die HTML-Antwort auf eine Navigationsanfrage im Cache zu speichern. Sie sollten normalerweise über das Netzwerk mit Cache-Control: no-cache erfüllt werden, damit der HTML-Code sowie die Kette nachfolgender Netzwerkanfragen (angemessene) aktuell sind. Wenn der Nutzer jedes Mal, wenn er eine neue Seite aufruft, in das Netzwerk wechselt, bedeutet das leider, dass jede Navigation möglicherweise langsam ist. Zumindest bedeutet das, dass sie nicht zuverlässig schnell ist.

Verschiedene Ansätze für Architekturen

Herauszufinden, wie auf Navigationsanfragen reagiert wird, ohne das Netzwerk zu umgehen, kann schwierig sein. Der richtige Ansatz hängt sehr stark von der Architektur Ihrer Website und der Anzahl der eindeutigen URLs ab, zu denen Nutzer möglicherweise gelangen.

Es gibt zwar keine Universallösung, aber die folgenden allgemeinen Richtlinien können Ihnen bei der Entscheidung helfen, welcher Ansatz am besten geeignet ist.

Kleine statische Websites

Wenn Ihre Webanwendung aus einer relativ kleinen Anzahl (z. B. ein paar Dutzend) eindeutiger URLs besteht und jede dieser URLs einer anderen statischen HTML-Datei entspricht, besteht ein möglicher Ansatz darin, alle diese HTML-Dateien im Cache zu speichern und auf Navigationsanfragen mit dem entsprechenden im Cache gespeicherten HTML-Code zu antworten.

Mit Precaching können Sie den HTML-Code im Voraus zwischenspeichern, sobald der Service Worker installiert ist, und ihn jedes Mal aktualisieren, wenn Sie Ihre Website neu erstellen und Ihren Service Worker noch einmal bereitstellen.

Wenn Sie es bevorzugen, nicht Ihren gesamten HTML-Code vorab im Cache zu speichern, weil Nutzer auf Ihrer Website möglicherweise nur zu einer Teilmenge der URLs navigieren, können Sie eine Laufzeit-Caching-Strategie des Typs stale-while-revalid verwenden. Seien Sie bei diesem Ansatz jedoch vorsichtig, da jedes einzelne HTML-Dokument separat im Cache gespeichert und aktualisiert wird. Das Laufzeit-Caching für HTML ist am besten geeignet, wenn Sie eine kleine Anzahl von URLs haben, die häufig von denselben Nutzern aufgerufen werden, und wenn Sie damit einverstanden sind, dass diese URLs unabhängig voneinander neu überprüft werden.

Apps mit nur einer Seite

Moderne Webanwendungen verwenden häufig eine Single-Page-Architektur. Darin ändert clientseitiges JavaScript den HTML-Code als Reaktion auf Nutzeraktionen. Dieses Modell verwendet die Verlaufs-API, um die aktuelle URL zu ändern, während der Nutzer mit der Webanwendung interagiert. Dies führt zu einer „simulierten“ Navigation. Nachfolgende Navigationen können zwar „falsch“ sein, die anfängliche Navigation ist jedoch real und es ist wichtig, darauf zu achten, dass sie im Netzwerk nicht blockiert ist.

Wenn Sie die Single-Page-Architektur verwenden, gibt es ein einfaches Muster für die Bereitstellung der ersten Navigation aus dem Cache: die Anwendungs-Shell. In diesem Modell antwortet der Service Worker auf Navigationsanfragen, indem er unabhängig von der angeforderten URL dieselbe, einzelne HTML-Datei zurückgibt, die bereits vorab im Cache gespeichert wurde. Dieser HTML-Code sollte einfach sein und vielleicht aus einem generischen Ladeindikator oder ursprünglichen Inhalten bestehen. Sobald der Browser diesen HTML-Code aus dem Cache geladen hat, übernimmt Ihr vorhandenes clientseitiges JavaScript und rendert den korrekten HTML-Inhalt für die URL aus der ursprünglichen Navigationsanfrage.

Workbox bietet die Tools, die Sie zur Implementierung dieses Ansatzes benötigen. Mit navigateFallback option können Sie angeben, welches HTML-Dokument als Anwendungs-Shell verwendet werden soll. Außerdem können Sie eine optionale Zulassungs- und Ablehnungsliste verwenden, um dieses Verhalten auf eine Teilmenge Ihrer URLs zu beschränken.

Mehrseitige Apps

Wenn Ihr Webserver den HTML-Code Ihrer Website dynamisch generiert oder Sie mehr als ein paar Dutzend einzelne Seiten haben, ist es viel schwieriger, das Netzwerk bei der Verarbeitung von Navigationsanfragen zu umgehen. Die Ratschläge unter Alles andere treffen wahrscheinlich auf Sie zu.

Bei einer bestimmten Teilmenge von mehrseitigen Anwendungen können Sie jedoch möglicherweise einen Service Worker implementieren, der die zum Generieren von HTML verwendete Logik auf Ihrem Webserver vollständig repliziert. Das funktioniert am besten, wenn Sie Routing- und Vorlageninformationen zwischen der Server- und der Service Worker-Umgebung freigeben können und insbesondere wenn Ihr Webserver JavaScript verwendet, ohne Node.js-spezifische Funktionen wie den Dateisystemzugriff zu verwenden.

Wenn Ihr Webserver in diese Kategorie fällt und Sie einen Ansatz kennenlernen möchten, um die HTML-Generierung vom Netzwerk weg in den Service Worker zu verschieben, können Ihnen die Anleitungen unter Mehr als SPAs: alternative Architekturen für Ihre PWA als Ausgangspunkt dienen.

Alles andere

Wenn Sie auf Navigationsanfragen nicht mit im Cache gespeicherten HTML-Code antworten können, müssen Sie dafür sorgen, dass die Navigation nicht durch das Hinzufügen eines Service Workers zu Ihrer Website verlangsamt wird, um andere Nicht-HTML-Anfragen zu verarbeiten. Wenn Sie den Service Worker starten, ohne ihn zum Antworten auf Navigationsanfragen zu verwenden, kommt es zu einer geringen Latenz (wie unter Schnellere und stabilere Anwendungen mit Service Worker erstellen beschrieben). Sie können diesen Aufwand reduzieren, indem Sie das Feature Navigation Preload aktivieren und dann die Netzwerkantwort verwenden, die in Ihrem fetch-Event-Handler vorab geladen wurde.

Die Workbox bietet eine Hilfsbibliothek, die erkennt, ob das Vorabladen der Navigation unterstützt wird. Ist dies der Fall, vereinfacht es die Anweisung des Service Workers zur Verwendung der Netzwerkantwort.

Foto von Aaron Burden auf Unsplash