Service Worker-Registrierung

Best Practices für den Zeitpunkt der Registrierung von Dienstarbeitern

Dienstworker können wiederholte Besuche Ihrer Webanwendung erheblich beschleunigen. Sie sollten jedoch dafür sorgen, dass die Erstinstallation eines Dienstworkers die Nutzererfahrung beim ersten Besuch nicht beeinträchtigt.

Im Allgemeinen ist es am besten, die Registrierung von Dienstprogrammen bis nach dem Laden der ersten Seite zu verschieben. Das ist besonders für Nutzer auf Mobilgeräten mit langsameren Netzwerkverbindungen von Vorteil.

Allgemeiner Registrierungs-Textbaustein

Wenn Sie schon einmal etwas über Service Worker gelesen haben, sind Sie wahrscheinlich auf Boilerplate-Code gestoßen, der in etwa so aussieht:

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

Dies kann manchmal durch einige console.log()-Anweisungen oder Code begleitet werden, der ein Update einer vorherigen Service Worker-Registrierung erkennt, um Nutzer darauf hinzuweisen, die Seite zu aktualisieren. Das sind aber nur geringfügige Abweichungen von den wenigen Standardcodezeilen.

Gibt es bei navigator.serviceWorker.register etwas zu beachten? Gibt es Best Practices, die ich beachten sollte? Wie nicht anders zu erwarten (da dieser Artikel nicht hier endet), lautet die Antwort auf beide Fragen „Ja“.

Der erste Besuch eines Nutzers

Betrachten wir den ersten Besuch eines Nutzers in einer Webanwendung. Es gibt noch keinen Service Worker und der Browser kann nicht im Voraus wissen, ob es einen Service Worker geben wird, der später installiert wird.

Als Entwickler sollten Sie dafür sorgen, dass der Browser schnell die minimalen kritischen Ressourcen erhält, die zum Anzeigen einer interaktiven Seite erforderlich sind. Alles, was das Abrufen dieser Antworten verlangsamt, ist ein Feind einer schnellen interaktiven Nutzung.

Angenommen, beim Herunterladen des JavaScripts oder der Bilder, die für das Rendern Ihrer Seite erforderlich sind, startet Ihr Browser einen Hintergrund-Thread oder -Prozess. Der Einfachheit halber gehen wir davon aus, dass es sich um einen Thread handelt. Angenommen, Sie verwenden kein leistungsstarkes Desktop-Gerät, sondern ein leistungsschwaches Smartphone, das viele Menschen als ihr Hauptgerät betrachten. Durch das Starten dieses zusätzlichen Threads kommt es zu Konflikten bei CPU-Zeit und Arbeitsspeicher, die Ihr Browser sonst für das Rendern einer interaktiven Webseite verwenden könnte.

Ein inaktiver Hintergrund-Thread wird wahrscheinlich keinen großen Unterschied machen. Was ist aber, wenn dieser Thread nicht inaktiv ist, sondern stattdessen entscheidet, dass er auch Ressourcen aus dem Netzwerk herunterladen soll? Bedenken hinsichtlich der CPU- oder Arbeitsspeicherauslastung sollten in den Hintergrund treten, da die Bandbreite vieler Mobilgeräte begrenzt ist. Die Bandbreite ist kostbar. Setzen Sie sie also nicht durch den gleichzeitigen Download sekundärer Ressourcen unnötig unter Druck.

Das bedeutet, dass das Starten eines neuen Service Worker-Threads zum Herunterladen und Caching von Ressourcen im Hintergrund Ihrem Ziel entgegenwirken kann, Nutzern beim ersten Besuch Ihrer Website eine möglichst kurze Reaktionszeit zu bieten.

Verbesserung des Standardtexts

Die Lösung besteht darin, den Start des Dienstarbeiters zu steuern, indem Sie festlegen, wann navigator.serviceWorker.register() aufgerufen werden soll. Als Faustregel gilt, die Registrierung so lange zu verzögern, bis load event auf window ausgelöst wird. Das würde so aussehen:

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

Der richtige Zeitpunkt für die Registrierung des Dienstarbeiters kann jedoch auch davon abhängen, was Ihre Webanwendung direkt nach dem Laden tut. Die Web-App der Google I/O 2016 zeigt beispielsweise eine kurze Animation, bevor der Hauptbildschirm angezeigt wird. Unser Team hat festgestellt, dass die Registrierung des Dienstarbeiters während der Animation zu Rucklern auf Low-End-Mobilgeräten führen kann. Anstatt die Nutzer zu verärgern, haben wir die Registrierung des Dienst-Workers auf nach der Animation verschoben, wenn der Browser am ehesten einige Sekunden inaktiv war.

Wenn Ihre Webanwendung ein Framework verwendet, das nach dem Laden der Seite eine zusätzliche Einrichtung durchführt, suchen Sie nach einem frameworkspezifischen Ereignis, das signalisiert, dass diese Arbeit abgeschlossen ist.

Folgebesuche

Bisher haben wir uns auf den ersten Besuch konzentriert. Welche Auswirkungen hat die verzögerte Registrierung von Dienstmitarbeitern auf wiederholte Besuche Ihrer Website? Das mag einige überraschen, aber es sollte keine Auswirkungen haben.

Wenn ein Service Worker registriert ist, durchläuft er die Lebenszyklusereignisse install und activate. Sobald ein Service Worker aktiviert ist, kann er fetch-Ereignisse für alle nachfolgenden Besuche Ihrer Webanwendung verarbeiten. Der Service Worker wird bevor die Anfrage für Seiten in seinem Umfang erfolgt gestartet. Das ist eigentlich ganz logisch. Wenn der vorhandene Dienst-Worker nicht bereits vor dem Besuch einer Seite ausgeführt wurde, kann er keine fetch-Ereignisse für Navigationsanfragen erfüllen.

Sobald also ein aktiver Dienst-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-Scripts nicht ändern, ist navigator.serviceWorker.register() bei nachfolgenden Besuchen inaktiv. Wann es aufgerufen wird, spielt keine Rolle.

Gründe für eine frühzeitige Registrierung

Gibt es Szenarien, in denen es sinnvoll ist, Ihren Dienst-Worker so früh wie möglich zu registrieren? Ein Beispiel wäre, wenn Ihr Service Worker clients.claim() verwendet, um die Kontrolle über die Seite beim ersten Besuch zu übernehmen, und der Service Worker im fetch-Handler aggressiv Laufzeit-Caching durchführt. In diesem Fall ist es von Vorteil, den Dienst-Worker so schnell wie möglich zu aktivieren, um seine Laufzeit-Caches mit Ressourcen zu füllen, die später nützlich sein könnten. Wenn Ihre Webanwendung in diese Kategorie fällt, sollten Sie sich vergewissern, dass der install-Handler Ihres Service Workers keine Ressourcen anfordert, die mit den Anfragen der Startseite um die Bandbreite konkurrieren.

Testen

Eine gute Möglichkeit, einen ersten Besuch zu simulieren, besteht darin, Ihre Webanwendung in einem Chrome-Inkognitofenster zu öffnen und sich den Netzwerkverkehr in den Chrome-Entwicklertools anzusehen. Als Webentwickler laden Sie wahrscheinlich mehrmals täglich 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, erhalten Sie nicht die gleiche Leistung wie ein neuer Nutzer. Außerdem ist es dann leicht, ein potenzielles Problem zu übersehen.

Hier ein Beispiel, das den Unterschied zeigt, den der Zeitpunkt der Registrierung ausmachen kann. Beide Screenshots wurden beim Besuch einer Beispiel-App im Inkognitomodus aufgenommen. Dabei wurde die Netzwerkdrosselung verwendet, um eine langsame Verbindung zu simulieren.

Netzwerkverkehr mit vorzeitiger Registrierung

Der Screenshot oben zeigt den Netzwerkverkehr, als das Beispiel so geändert wurde, dass die Registrierung des Dienst-Workers so schnell wie möglich durchgeführt wurde. Sie sehen Precaching-Anfragen (die Einträge mit dem Zahnradsymbol daneben, die vom install-Handler des Service Workers stammen) zwischen Anfragen für die anderen Ressourcen, die zum Anzeigen der Seite erforderlich sind.

Netzwerkverkehr mit verspäteter Registrierung

Im Screenshot oben wurde die Registrierung des Service Workers verzögert, bis die Seite geladen war. Wie Sie sehen, werden die Pre-Caching-Anfragen erst gestartet, wenn alle Ressourcen aus dem Netzwerk abgerufen wurden. So wird jeglicher Bandbreitenkonflikt vermieden. Da sich einige der Elemente, die wir vorab im Cache speichern, 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, wenn Sie diese Art von Test auf einem echten Low-End-Gerät in einem echten Mobilfunknetz ausführen. Sie können die Remote-Debugging-Funktionen von Chrome nutzen, um ein Android-Smartphone über USB mit Ihrem Computer zu verbinden und dafür zu sorgen, dass die von Ihnen durchgeführten Tests die tatsächliche Nutzung durch viele Ihrer Nutzer widerspiegeln.

Fazit

Zusammenfassend lässt sich sagen, dass der erste Besuch Ihrer Website für Nutzer möglichst positiv sein sollte. Sie können dies erreichen, indem Sie die Registrierung des Dienst-Workers verzögern, bis die Seite beim ersten Besuch geladen wurde. Sie profitieren weiterhin von allen Vorteilen eines Service Workers bei wiederholten Besuchen.

Mit der folgenden Methode können Sie die Erstregistrierung Ihres Service Workers so verzögern, dass sie erst nach dem Laden der ersten Seite erfolgt:

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