Progressive Web-Apps: Mit Workern arbeiten

1. Willkommen

In diesem Lab fügen Sie einer vorhandenen Webanwendung einen Web-Worker hinzu, um den Status zwischen zwei geöffneten Fenstern zu teilen. Dies ist das achte in einer Reihe von Codelabs für den Progressive Web App-Workshop. Das vorherige Codelab hieß Service Worker Includes. Dies ist das letzte Codelab in der Reihe.

Lerninhalte

  • Shared Worker zwischen mehreren geöffneten Fenstern hinzufügen
  • Comlink verwenden, um die Zusammenarbeit mit Workern zu erleichtern

Wichtige Informationen

  • JavaScript

Voraussetzungen

2. Einrichtung

Klonen oder laden Sie zuerst den Starter-Code herunter, der für dieses Codelab benötigt wird:

Wenn Sie das Repository klonen, achten Sie darauf, dass Sie sich im pwa06--working-with-workers-Branch befinden. Die ZIP-Datei enthält auch den Code für diesen Zweig.

Für diese Codebasis ist Node.js 14 oder höher erforderlich. Sobald Sie den Code haben, führen Sie npm ci über die Befehlszeile im Ordner des Codes aus, um alle erforderlichen Abhängigkeiten zu installieren. Führen Sie dann npm start aus, um den Entwicklungsserver für das Codelab zu starten.

Die README.md-Datei des Quellcodes enthält eine Erklärung für alle verteilten Dateien. Außerdem sind die folgenden Dateien wichtig, mit denen Sie in diesem Codelab arbeiten werden:

Schlüsseldateien

  • js/preview.js – JavaScript-Datei für die Vorschauseite
  • js/main.js – JavaScript-Datei der Hauptanwendung

3. Worker schreiben

Derzeit werden in der Vorschaufunktion Ihrer Web-App nur die neuesten Inhalte beim Laden angezeigt. Im Idealfall wird eine Live-Vorschau angezeigt, während der Nutzer tippt. Dazu müssen Sie möglicherweise große Datenmengen zusammenstellen und zwischen zwei verschiedenen geöffneten Fenstern übertragen. Daher sollte dies nicht im Hauptthread eines der geöffneten Fenster erfolgen. Stattdessen verwenden wir einen gemeinsam genutzten Web-Worker.

Erstellen Sie zuerst eine Datei js/worker.js mit dem folgenden Code:

import { expose } from 'comlink';
import { marked } from 'marked';

class Compiler {
  state = {
    raw: '',
    compiled: '',
  };
  subscribers = [];

  async set(content) {
    this.state = {
      raw: content,
      compiled: marked(content),
    };

    await Promise.all(this.subscribers.map((s) => s(this.state)));
  }

  subscribe(cb) {
    this.subscribers.push(cb);
  }
}

const compiler = new Compiler();

onconnect = (e) => expose(compiler, e.ports[0]);

Erklärung

Mit diesem Code wird eine Klasse namens Compiler eingerichtet, mit der Inhalte festgelegt und Abonnements aufgerufen werden können, sobald die Inhalte kompiliert wurden. Da es sich um einen Shared Worker handelt, sollte nur eine Instanz dieser Klasse verwendet werden. Daher wird eine neue Instanz von Compiler instanziiert. Damit die Arbeit mit dieser Klasse von außerhalb des Workers nahtlos möglich ist, wird Comlink verwendet, um die Compiler-Instanz verfügbar zu machen. So können wir alle Methoden darauf verwenden, als wäre sie im Code deklariert, der sie verwendet. Da es sich um einen gemeinsam genutzten Worker und nicht um einen dedizierten Worker handelt, muss er für alle Verbindungen verfügbar sein.

4. Inhalte an den Worker senden

Nachdem wir den Worker erstellt haben, müssen wir ihm Inhalte senden. Aktualisieren Sie dazu js/main.js, um Folgendes zu tun:

  • Benannten Export wrap aus comlink importieren
  • Erstellen Sie einen neuen Shared Worker vom Typ „Modul“ namens worker, legen Sie den Typ auf module fest und verweisen Sie mit dem Muster new URL darauf (new URL('./worker.js', import.meta.url)).
  • Erstellen Sie eine compiler-Variable, die wrap für die worker.port ist.
  • Warten Sie in der Aktualisierungsfunktion des Editors (editor.onUpdate) nach dem Speichern von Inhalten in der Datenbank, bis compiler.set abgeschlossen ist, und übergeben Sie die Inhalte.

Erklärung

Durch das Umschließen eines Comlink-Exports können beispielsweise freigegebene Klassenmethoden so verwendet werden, als ob sie nicht über eine Worker-Grenze hinweg freigegeben wären. Die Ausnahme ist, dass jetzt alles asynchron ist. Da es sich um einen gemeinsam genutzten Worker und nicht um einen dedizierten Worker handelt, muss Comlink den Port des Workers und nicht den Worker selbst umschließen. Wenn der Editor aktualisiert wird, werden die Inhalte an den Worker gesendet, damit er sie verarbeitet.

5. Vorschauseite aktualisieren

Im letzten Schritt müssen Sie die kompilierten Inhalte aus dem Shared Worker in die Vorschau übertragen. Die Einrichtung ist weitgehend dieselbe, aber da Funktionen nicht zwischen Worker-Grenzen übergeben werden können, muss stattdessen ein Proxy für die Funktion verwendet werden. Comlink kann Ihnen dabei helfen. Aktualisieren Sie js/preview.js, damit Folgendes möglich ist:

  • Benannte Exporte wrap und proxy aus comlink importieren
  • Erstellen und umschließen Sie den Shared Worker wie in js/main.js beschrieben.
  • Rufen Sie die subscribe-Methode des Compilers mit einer Proxy-Funktion auf, die die compiled-Eigenschaft der eingehenden Daten auf den inneren HTML-Code des Vorschau-Bereichs festlegt.

Öffnen Sie dann die Vorschau, beginnen Sie mit der Eingabe im Editor und lassen Sie sich davon überraschen, wie Ihr Markdown automatisch kompiliert und in Echtzeit im Vorschau-Bereich angezeigt wird, ohne dass der Hauptthread der Seite blockiert wird.

6. Glückwunsch!

Sie haben gelernt, wie Sie einen Shared Worker verwenden, um den Status zwischen mehreren PWA-Instanzen freizugeben.