Schalten Sie Ihre App mit Service Workern offline

- Seite 1: Schnelleres Laden
- Seite 2: Offline-Zugriff hinzufügen
Service Worker können verwendet werden, um die Ladezeiten und die Offline-Unterstützung für Ihre Websites und Webanwendungen zu verbessern. In diesem Tutorial zeigen wir Ihnen, wie Sie eine Web-App mit einem Service Worker schrittweise verbessern können. Zuerst werden wir behandeln, was ein Service Worker ist und wie sein Lebenszyklus funktioniert, dann werden wir Ihnen zeigen, wie Sie dann Ihre Website (diese Seite) beschleunigen und Offline-Inhalte anbieten (Seite 2).
Dann zeigen wir Ihnen, wie es geht Wie erstelle ich eine App? mit Servicemitarbeitern. Sie erfahren, wie Sie einen Bare-Bones-Worker einrichten, der statische Assets zwischenspeichert und bereitstellt (was bei nachfolgenden Ladevorgängen einen enormen Leistungsschub bringt), wie Sie dynamische API-Antworten zwischenspeichern und unserer Demo-App vollständige Offline-Unterstützung bieten. Schauen wir uns zunächst an, was genau Service Worker sind und wie sie funktionieren.
Eine Website erstellen? Optimieren Sie Ihren Prozess mit einem großartigen Webseitenersteller und pflegen Sie es mit einem anständigen Web-Hosting Bedienung. Und sortieren Sie Ihren Speicher damit Cloud-Speicher Optionen.
Was ist ein Servicemitarbeiter?
Was ist ein Servicemitarbeiter? Es ist ein in JavaScript geschriebenes Skript, das Ihr Browser im Hintergrund ausführt. Dies hat keine Auswirkungen auf den Hauptthread (in dem JavaScript normalerweise auf einer Webseite ausgeführt wird) und steht nicht in Konflikt mit Ihrem App-Code oder beeinträchtigt die Laufzeitleistung.
Ein Service Worker hat keinen direkten Zugriff auf das DOM oder Ereignisse und Benutzerinteraktionen, die auf der Webseite selbst stattfinden. Stellen Sie sich das als eine Ebene vor, die sich zwischen der Webseite und dem Netzwerk befindet und es ermöglicht, Netzwerkanforderungen (z. B. Ajax-Anforderungen), die von Ihrer Seite gestellt werden, abzufangen und zu bearbeiten. Dies macht es ideal für die Verwaltung von Caches und die Unterstützung der Offline-Nutzung.
Der Service Worker-Lebenszyklus
Das Leben eines Service Workers verläuft in einem einfachen Ablauf, aber es kann etwas verwirrend sein, wenn Sie an JS-Skripte gewöhnt sind, die nur sofort funktionieren:
Installieren> Warten (installiert)> Aktivieren> Aktiviert> Redundant
Wenn Ihre Seite zum ersten Mal geladen wird, den Registrierungscode, den wir hinzugefügt haben index.html Startet die Installation des Service Worker. Wenn kein Worker vorhanden ist, wird der neue Service Worker sofort nach der Installation aktiviert. Auf einer Webseite kann jeweils nur ein Service Worker aktiv sein.
Wenn bereits ein Worker installiert ist, wird der neue Service Worker installiert und wartet dann, bis die Seite vollständig geschlossen und dann neu geladen ist. Eine einfache Aktualisierung reicht nicht aus, da möglicherweise andere Registerkarten geöffnet sind. Sie müssen sicherstellen, dass alle Instanzen der Seite geschlossen sind, da sonst der neue Worker nicht aktiviert wird. Sie müssen die Registerkarten nicht schließen, sondern können einfach zu einer anderen Site navigieren und zurückkehren.
Beide Installieren und aktivieren Sie Ereignisse treten nur einmal pro Mitarbeiter auf. Nach der Aktivierung hat der Service Worker die Kontrolle über die Seite und kann Ereignisse wie das Abrufen verarbeiten, um Anforderungen zu bearbeiten.
Schließlich wird ein Service Worker überflüssig, wenn der Browser feststellt, dass die Worker-Datei selbst aktualisiert wurde oder wenn die Installation oder Aktivierung fehlschlägt. Der Browser sucht nach einem Byteunterschied, um festzustellen, ob ein Arbeitsskript aktualisiert wurde.
Es ist wichtig zu beachten, dass Sie den Namen Ihres Servicemitarbeiters niemals ändern (oder revidieren) sollten. Sie sollten die Worker-Datei auch nicht auf dem Server zwischenspeichern, da Sie sie nicht einfach aktualisieren können, obwohl Browser jetzt intelligent genug sind, um das Zwischenspeichern von Headern zu ignorieren.
01. Klonen Sie die Demo-App
Okay, lassen Sie uns lernen, wie Sie mithilfe von Servicemitarbeitern eine Web-App erstellen. Für dieses Tutorial benötigen Sie aktuelle Versionen von Node.js und npm, die auf Ihrem Computer installiert sind.
Wir haben eine Demo-App erstellt, die wir als Grundlage für dieses Tutorial verwenden werden ( Klonen Sie die Demo-App hier ). Die App ist ein lustiges kleines Projekt, das die fünftägige Wettervorhersage basierend auf dem Standort des Benutzers abruft. Anschließend wird geprüft, ob vor Tagesende Regen vorhergesagt wird, und die Benutzeroberfläche wird entsprechend aktualisiert.
Es wurde ineffizient (absichtlich) mit großen, unnötigen Bibliotheken wie jQuery und Bootstrap erstellt, mit großen, nicht optimierten Images, um den Leistungsunterschied bei der Verwendung eines Service Worker zu demonstrieren. Es wiegt derzeit lächerliche 4,1 MB.
02. Holen Sie sich Ihren API-Schlüssel
Um die Wetterdaten von der API abzurufen, benötigen Sie einen kostenlosen API-Schlüssel von OpenWeatherMap ::
Sobald Sie Ihren Schlüssel haben, öffnen Sie index.html und suchen Sie die window.API_KEY Variable in der . Fügen Sie Ihren Schlüssel in den Wert ein:
window.API_KEY = 'paste-your-key-here';
03. Starten Sie den Entwicklungsserver
Jetzt können wir mit der Arbeit an dem Projekt beginnen. Lassen Sie uns zunächst die Abhängigkeiten installieren, indem Sie Folgendes ausführen:
npm install
Es gibt zwei Aufgaben für das Build-Tool. Lauf über dem Meeresspiegel beginnen um den Entwicklungsserver auf Port 3000 zu starten. Ausführen npm run build um die 'Produktions'-Version vorzubereiten. Denken Sie daran, dass dies nur eine Demo ist, also nicht wirklich eine Produktionsversion - es gibt keine Minimierung oder irgendetwas - die Dateien werden nur 'überarbeitet'.
Ein Algorithmus wird verwendet, um aus dem Inhalt der Datei einen Hash wie 9c616053e5 zu erstellen. Der Algorithmus gibt immer denselben Hash für denselben Inhalt aus. Dies bedeutet, dass sich der Hash nicht ändert, solange Sie die Datei nicht ändern. Der Hash wird dann an den Dateinamen angehängt, sodass beispielsweise styles.css zu styles-9c616053e5.css werden kann. Der Hash repräsentiert die Revision der Datei - daher 'revidiert'.
Sie können jede Version der Datei auf Ihrem Server sicher zwischenspeichern, ohne jemals Ihren Cache ungültig machen zu müssen, was teuer ist, oder sich Sorgen machen, dass ein anderer Cache eines Drittanbieters die falsche Version bereitstellt.
04. Stellen Sie Ihren Servicemitarbeiter vor
Beginnen wir jetzt mit unserem Servicemitarbeiter. Erstellen Sie eine Datei mit dem Namen sw.js im Stammverzeichnis von src Verzeichnis. Fügen Sie dann diese beiden Ereignis-Listener hinzu, um die zu protokollieren Installieren und aktivieren Sie Veranstaltungen:
self.addEventListener('install', (event) => { console.log(event); }); self.addEventListener('activate', (event) => { console.log(event); });
Das selbst Die Variable repräsentiert hier den globalen schreibgeschützten Bereich des Service Workers. Es ist ein bisschen wie das Fenster Objekt in einer Webseite.
Als Nächstes müssen wir unsere Datei index.html aktualisieren und die Befehle zum Installieren des Service Worker hinzufügen. Fügen Sie dieses Skript kurz vor dem Schließen hinzu Etikett. Es wird unseren Mitarbeiter registrieren und seinen aktuellen Status protokollieren.
if ('serviceWorker' in navigator) { navigator.serviceWorker.register('/sw.js') .then(function(reg) { if (reg.installing) { console.log('SW installing'); } else if (reg.waiting) { console.log('SW waiting'); } else if (reg.active) { console.log('SW activated'); } }).catch(function(error) { // registration failed console.log('Registration failed with ' + error); }); }
Starten Sie Ihren Entwicklungsserver durch Ausführen über dem Meeresspiegel beginnen und öffnen Sie die Seite in einem modernen Browser. Wir empfehlen die Verwendung von Google Chrome, da die DevTools einen guten Service-Worker-Support bieten, auf den wir in diesem Lernprogramm verweisen. Sie sollten drei Dinge sehen, die an Ihrer Konsole protokolliert sind. zwei vom Servicemitarbeiter für die Installieren und aktivieren Sie Ereignisse, und das andere wird die Nachricht von der Registrierung sein.
05. Aktivieren Sie den Worker
Wir werden unseren Mitarbeitern sagen, dass sie den Warteschritt überspringen und jetzt aktivieren sollen. Öffnen Sie die Datei sw.js und fügen Sie diese Zeile an einer beliebigen Stelle in der Datei hinzu Installieren Ereignis-Listener:
self.skipWaiting();
Wenn wir jetzt das Worker-Skript aktualisieren, übernimmt es unmittelbar nach der Installation die Kontrolle über die Seite. Beachten Sie, dass dies bedeuten kann, dass der neue Worker die Kontrolle über eine Seite übernimmt, die möglicherweise von einer früheren Version Ihres Workers geladen wurde. Wenn dies zu Problemen führen wird, verwenden Sie diese Option nicht in Ihrer App.
Sie können dies bestätigen, indem Sie von der Seite weg navigieren und dann zurückkehren. Sie sollten das sehen Installieren und aktivieren Sie Ereignisse werden erneut ausgelöst, wenn der neue Worker installiert wurde.
Chrome DevTools bietet eine hilfreiche Option, mit der Sie Ihren Worker einfach durch erneutes Laden aktualisieren können. Öffnen Sie DevTools, wechseln Sie zur Registerkarte Anwendung und wählen Sie in der linken Spalte Service Worker aus. Am oberen Rand des Bedienfelds befindet sich ein Kontrollkästchen mit der Bezeichnung Beim erneuten Laden aktualisieren. Aktivieren Sie es. Ihr aktualisierter Worker wird jetzt beim Aktualisieren installiert und aktiviert.
06. Änderungen bestätigen
Lassen Sie uns dies durch Hinzufügen bestätigen console.log ('foo') Rufen Sie einen der Ereignis-Listener an und aktualisieren Sie die Seite. Dies hat uns überrascht, weil wir erwartet hatten, dass das Protokoll in der Konsole angezeigt wird, wenn wir es aktualisieren, aber alles, was wir sahen, war die Meldung 'SW aktiviert'. Es stellt sich heraus, dass Chrome die Seite zweimal aktualisiert, wenn die Option Beim erneuten Laden aktualisieren aktiviert ist.
Sie können dies bestätigen, indem Sie das Kontrollkästchen Protokoll beibehalten im Bereich Konsoleneinstellungen aktivieren und erneut aktualisieren. Sie sollten die protokollierten Installations- und Aktivierungsereignisse zusammen mit 'foo' gefolgt von 'Navigiert zu http: // localhost: 3000 /' sehen, um anzuzeigen, dass die Seite neu geladen wurde, und dann die letzte Meldung 'SW aktiviert'.
07. Verfolgen Sie das Abrufereignis
Zeit, einen weiteren Listener hinzuzufügen. Dieses Mal werden wir die verfolgen holen Ereignis, das jedes Mal ausgelöst wird, wenn die Seite eine Ressource lädt, z. B. eine CSS-Datei, ein Bild oder sogar eine API-Antwort. Wir öffnen einen Cache, geben die Anforderungsantwort an die Seite zurück und zwischenspeichern dann im Hintergrund die Antwort. Fügen wir zunächst den Listener hinzu und aktualisieren Sie ihn, damit Sie sehen können, was passiert. In der Konsole sollten Sie viele sehen FetchEvent Protokolle.
self.addEventListener('fetch', (event) => { console.log(event); });
Unser Serve-Modus verwendet BrowserSync, das der Seite ein eigenes Skript hinzufügt und Websocket-Anforderungen stellt. Sie werden auch die FetchEvents für diese sehen, aber wir möchten diese ignorieren. Wir möchten auch nur GET-Anfragen von unserer eigenen Domain zwischenspeichern. Fügen wir also einige Dinge hinzu, um unerwünschte Anforderungen zu ignorieren, einschließlich des expliziten Ignorierens der /. Indexpfad:
self.addEventListener('fetch', (event) => { // Ignore crossdomain requests if (!event.request.url.startsWith(self.location.origin)) { return; } // Ignore non-GET requests if (event.request.method !== 'GET') { return; } // Ignore browser-sync if (event.request.url.indexOf('browser-sync') > -1) { return; } // Prevent index route being cached if (event.request.url === (self.location.origin + '/')) { return; } // Prevent index.html being cached if (event.request.url.endsWith('index.html')) { return; } console.log(event); });
Jetzt sollten die Protokolle viel sauberer sein und es ist sicher, mit dem Caching zu beginnen.
08. Cache die Assets
Jetzt können wir diese Antworten zwischenspeichern. Zuerst müssen wir unserem Cache einen Namen geben. Rufen wir unsere an v1-Assets . Fügen Sie diese Zeile oben in die Datei sw.js ein:
const assetsCacheName = 'v1-assets';
Dann müssen wir die FetchEvents entführen, damit wir steuern können, was auf die Seite zurückgegeben wird. Wir können das mit den Ereignissen machen Antworten mit Methode. Diese Methode akzeptiert ein Versprechen, damit wir diesen Code hinzufügen und den ersetzen können console.log ::
// Tell the fetch to respond with this Promise chain event.respondWith( // Open the cache caches.open(assetsCacheName) .then((cache) => { // Make the request to the network return fetch(event.request) .then((response) => { // Cache the response cache.put(event.request, response.clone()); // Return the original response to the page return response; }); }) );
Dadurch wird die Anforderung an das Netzwerk weitergeleitet und die Antwort im Cache gespeichert, bevor die ursprüngliche Antwort an die Seite zurückgesendet wird.
Hierbei ist zu beachten, dass bei diesem Ansatz die Antworten erst beim zweiten Laden der Seite zwischengespeichert werden. Das erste Mal wird der Worker installiert und aktiviert, aber bis zum holen Hörer ist bereit, alles wurde bereits angefordert.
Aktualisieren Sie einige Male und überprüfen Sie den Cache auf der Registerkarte DevTools> Anwendung. Erweitern Sie den Cache-Speicherbaum in der linken Spalte, und Sie sollten Ihren Cache mit allen gespeicherten Antworten sehen.
09. Aus dem Cache servieren
Alles wird zwischengespeichert, aber wir verwenden den Cache noch nicht, um Dateien bereitzustellen. Lassen Sie uns das jetzt anschließen. Zuerst suchen wir nach einer Übereinstimmung für die Anforderung im Cache, und falls vorhanden, werden wir diese bedienen. Wenn es nicht existiert, verwenden wir das Netzwerk und zwischenspeichern die Antwort.
// Tell the fetch to respond with this chain event.respondWith( // Open the cache caches.open(assetsCacheName) .then((cache) => { // Look for matching request in the cache return cache.match(event.request) .then((matched) => { // If a match is found return the cached version first if (matched) { return matched; } // Otherwise continue to the network return fetch(event.request) .then((response) => { // Cache the response cache.put(event.request, response.clone()); // Return the original response to the page return response; }); }); }) );
Speichern Sie die Datei und aktualisieren Sie sie. Überprüfen Sie die Registerkarte DevTools> Netzwerk, und Sie sollten (von ServiceWorker) in der Spalte Größe für jedes der statischen Assets aufgelistet sehen.
Puh, wir sind fertig. Für so wenig Code gibt es viel zu verstehen. Sie sollten sehen, dass das Aktualisieren der Seite, sobald alle Assets zwischengespeichert sind, ziemlich schnell ist. Lassen Sie uns jedoch eine schnelle (unwissenschaftliche) Überprüfung der Ladezeiten für eine gedrosselte Verbindung durchführen (Registerkarte DevTools> Netzwerk).
Ohne den Service Worker dauert das Laden über ein simuliertes schnelles 3G-Netzwerk fast 30 Sekunden, bis alles geladen ist. Mit dem Service Worker, der dieselbe gedrosselte Verbindung hat, aber aus dem Cache geladen wird, dauert es knapp eine Sekunde.
Aktivieren Sie das Kontrollkästchen Offline und aktualisieren Sie, und Sie werden feststellen, dass die Seite ohne Verbindung geladen wird, obwohl die Prognosedaten nicht von der API abgerufen werden können. Auf Seite 2 kehren wir dazu zurück und erfahren, wie Sie auch die API-Antwort zwischenspeichern.
Nächste Seite: Verwenden Sie Service Worker, um Online-Zugriff anzubieten
- 1
- zwei
Aktuelle Seite: Seite 1: Schnelleres Laden
Nächste Seite Seite 2: Offline-Zugriff hinzufügen