Service Worker-Registrierung

Best Practices für den zeitlichen Ablauf der Service Worker-Registrierung

Service Worker können wiederholte Besuche Ihrer Webanwendung erheblich beschleunigen. Sie sollten jedoch Maßnahmen ergreifen, um sicherzustellen, dass die Erstinstallation eines Service Workers die Nutzererfahrung beim ersten Besuch nicht beeinträchtigt.

Im Allgemeinen ist es für Nutzer von Vorteil, die Service Worker-Registrierung erst nach dem Laden der ersten Seite zu verzögern. Dies gilt insbesondere für Mobilgeräte mit langsameren Netzwerkverbindungen.

Boilerplate für die allgemeine Registrierung

Wenn Sie jemals über Service Worker gelesen haben, sind Sie wahrscheinlich auf Boilerplate gestoßen, die im Wesentlichen folgenden ähnelt:

if ('serviceWorker' in navigator) {
    navigator.serviceWorker.register('/service-worker.js');
}

Dies kann manchmal zusammen mit einigen console.log()-Anweisungen oder Code vorkommen, mit dem eine Aktualisierung einer vorherigen Service Worker-Registrierung erkannt wird, damit Nutzer wissen, dass sie die Seite aktualisieren müssen. Aber das sind nur kleine Variationen der Standard-Codezeilen.

Gibt es bei navigator.serviceWorker.register also irgendwelche Nuancen? Gibt es Best Practices, die Sie befolgen sollten? Es überrascht nicht, dass die Antwort auf beide „Ja!“ lautet (da dieser Artikel nicht gleich hier endet).

Erster Besuch eines Nutzers

Nehmen wir einmal den ersten Besuch eines Nutzers bei einer Webanwendung an. Es gibt noch keinen Service Worker und der Browser kann nicht im Voraus wissen, ob ein Service Worker installiert wird.

Als Entwickler sollten Sie darauf achten, dass der Browser schnell auf die minimalen kritischen Ressourcen zugreift, die zum Anzeigen einer interaktiven Seite erforderlich sind. Alles, was das Abrufen dieser Antworten verlangsamt, ist der Gegner einer schnellen Time-to-interaktiv-Erfahrung.

Stellen Sie sich nun vor, dass Ihr Browser beim Herunterladen des JavaScript oder der Bilder, das Ihre Seite rendern muss, einen Hintergrund-Thread oder Prozess startet (aus Gründen der Kürze gehen wir davon aus, dass es sich um einen Thread handelt). Angenommen, Sie arbeiten nicht mit einem leistungsstarken Desktop-Computer, sondern mit einem leistungsschwachen Mobiltelefon, das die meisten Menschen weltweit als primäres Gerät betrachten. Das Starten dieses zusätzlichen Threads führt zu Konflikten hinsichtlich der CPU-Zeit und des Arbeitsspeichers, die Ihr Browser andernfalls mit dem Rendern einer interaktiven Webseite verbringen würde.

Ein inaktiver Hintergrundthread wird wahrscheinlich keinen nennenswerten Unterschied machen. Aber was ist, wenn dieser Thread nicht inaktiv ist, sondern stattdessen entscheidet, dass er auch Ressourcen aus dem Netzwerk herunterlädt? Bei Bedenken hinsichtlich CPU- oder Speicherkonflikten sollten Sie sich Gedanken über die begrenzte Bandbreite machen, die vielen Mobilgeräten zur Verfügung steht. Die Bandbreite ist kostbar. Daher sollten Sie kritische Ressourcen nicht dadurch untergraben, dass gleichzeitig Sekundärressourcen heruntergeladen werden.

All dies soll Ihnen sagen, dass das Starten eines neuen Service-Worker-Threads zum Herunterladen und Speichern von Ressourcen im Hintergrund Ihnen helfen kann, die kürzeste Zeit bis zur interaktiven Interaktion zu bieten, wenn ein Nutzer Ihre Website zum ersten Mal besucht.

Verbessern des Textbausteins

Die Lösung besteht darin, den Start des Service Workers zu steuern, indem Sie festlegen, wann navigator.serviceWorker.register() aufgerufen werden soll. Eine einfache Faustregel wäre, die Registrierung zu verschieben, bis das load event-Objekt am window ausgelöst wird. Beispiel:

if ('serviceWorker' in navigator) {
    window.addEventListener('load', function() {
    navigator.serviceWorker.register('/service-worker.js');
    });
}

Der richtige Zeitpunkt für den Beginn der Service Worker-Registrierung kann jedoch auch davon abhängen, was Ihre Webanwendung unmittelbar nach dem Laden tut. Die Google I/O-Web-App 2016 enthält beispielsweise eine kurze Animation, bevor zum Hauptbildschirm gewechselt wird. Unser Team hat festgestellt, dass das Starten der Service Worker-Registrierung während der Animation auf Low-End-Mobilgeräten zu Verzögerungen führen kann. Anstatt die Nutzer zu stören, haben wir die Registrierung von Service Workern verzögert, bis die Animation abgeschlossen ist, da der Browser am ehesten ein paar Sekunden inaktiv war.

Wenn Ihre Webanwendung ein Framework verwendet, das nach dem Laden der Seite zusätzliche Einrichtungen ausführt, suchen Sie nach einem Framework-spezifischen Ereignis, das signalisiert, wann diese Arbeit erledigt ist.

Aufeinander folgende Besuche

Bis jetzt haben wir uns auf den ersten Besuch konzentriert. Aber wie wirkt sich die verzögerte Registrierung von Service Workern auf wiederholte Besuche deiner Website aus? Das mag manche Menschen vielleicht überraschen, aber es sollte überhaupt keine Auswirkungen haben.

Wenn ein Service Worker registriert ist, durchläuft er die Lebenszyklusereignisse install und activate. Sobald ein Service Worker aktiviert wurde, kann er fetch-Ereignisse bei nachfolgenden Besuchen Ihrer Webanwendung verarbeiten. Er wird gestartet, bevor die Anfrage für Seiten unter seinem Geltungsbereich erfolgt. Dies ist sinnvoll, wenn man darüber nachdenkt. Wenn der vorhandene Service Worker vor dem Aufrufen einer Seite nicht bereits ausgeführt wird, wäre er nicht in der Lage, fetch-Ereignisse für Navigationsanfragen auszuführen.

Sobald also ein aktiver Service Worker vorhanden ist, spielt es keine Rolle, wann Sie navigator.serviceWorker.register() aufrufen oder ob Sie ihn überhaupt aufrufen. Sofern Sie die URL des Service Worker-Skripts nicht ändern, ist navigator.serviceWorker.register() bei nachfolgenden Besuchen einsatzlos. Es ist irrelevant, wenn es aufgerufen wird.

Gründe für eine frühzeitige Registrierung

Gibt es Szenarien, in denen die Registrierung Ihres Service Workers so früh wie möglich sinnvoll ist? Ein Beispiel hierfür ist, wenn der Service Worker beim ersten Besuch clients.claim() verwendet, um die Seite zu verwalten, und er innerhalb seines fetch-Handlers aggressiv Laufzeit-Caching durchführt. In dieser Situation hat es den Vorteil, dass der Service Worker so schnell wie möglich aktiviert wird, damit seine Laufzeit-Caches mit Ressourcen gefüllt werden, die sich später als nützlich erweisen könnten. Wenn Ihre Webanwendung in diese Kategorie fällt, sollten Sie einen Schritt zurücktreten, um dafür zu sorgen, dass der install-Handler Ihres Service Workers keine Ressourcen anfordert, die bei den Anfragen der Hauptseite um Bandbreite kämpfen.

Dinge testen

Eine gute Möglichkeit, einen ersten Besuch zu simulieren, besteht darin, die Web-App in einem Chrome-Inkognitofenster zu öffnen und sich den Netzwerkverkehr in den Chrome-Entwicklertools anzusehen. Als Webentwickler laden Sie wahrscheinlich Dutzende Male pro Tag eine lokale Instanz Ihrer Webanwendung neu. Wenn Sie Ihre Website jedoch noch einmal aufrufen, wenn bereits ein Service Worker und vollständig gefüllte Caches vorhanden sind, profitieren Sie nicht von der gleichen Nutzererfahrung wie ein neuer Nutzer und es ist leicht, ein potenzielles Problem zu ignorieren.

Hier ist ein Beispiel, das den Unterschied zwischen dem Registrierungszeitpunkt verdeutlicht. Beide Screenshots werden beim Aufrufen einer Beispiel-App im Inkognitomodus mit Netzwerkdrosselung aufgenommen, um eine langsame Verbindung zu simulieren.

Netzwerkverkehr mit frühzeitiger Registrierung.

Im Screenshot oben ist der Netzwerkverkehr zu sehen, als das Beispiel geändert wurde, um so schnell wie möglich eine Service Worker-Registrierung durchzuführen. Sie sehen, dass Precaching-Anfragen (die Einträge mit dem Zahnradsymbol daneben, die aus dem install-Handler des Service Workers stammen) und Anfragen für die anderen Ressourcen unterbrochen haben, die zum Anzeigen der Seite erforderlich sind.

Netzwerkverkehr mit verspäteter Registrierung.

Im Screenshot oben wurde die Service Worker-Registrierung erst nach dem Laden der Seite verzögert. Die Precaching-Anfragen werden erst gestartet, wenn alle Ressourcen aus dem Netzwerk abgerufen wurden. Dadurch werden Konflikte bezüglich der Bandbreite beseitigt. Da sich einige der Elemente, die im Cache gespeichert werden, bereits im HTTP-Cache des Browsers befinden (die Elemente mit (from disk cache) in der Spalte „Größe“), können wir den Cache des Service Workers füllen, ohne noch einmal das Netzwerk aufrufen zu müssen.

Bonuspunkte gibt es, wenn Sie diese Art von Test auf einem Low-End-Gerät in einem echten Mobilfunknetz durchführen. Sie können die Remote-Debugging-Funktionen von Chrome nutzen, um ein Android-Smartphone über USB an Ihren Desktop-Computer anzuschließen und dafür zu sorgen, dass die von Ihnen ausgeführten Tests die realen Erfahrungen vieler Ihrer Nutzer widerspiegeln.

Fazit

Zusammenfassend lässt sich sagen, dass die Nutzerfreundlichkeit beim ersten Besuch oberste Priorität haben sollte. Dies kann hilfreich sein, wenn Sie die Registrierung von Service Workern auf später verschieben, nachdem die Seite während des ersten Besuchs geladen wurde. Sie profitieren dennoch von allen Vorteilen, die ein Service Worker für Ihre wiederholten Besuche bietet.

So können Sie die Erstregistrierung Ihres Service Workers erst nach dem Laden der ersten Seite verzögern:

if ('serviceWorker' in navigator) {
    window.addEventListener('load', function() {
    navigator.serviceWorker.register('/service-worker.js');
    });
}