1. Ti diamo il benvenuto
In questo lab, prenderai un'applicazione web esistente e aggiungerai un web worker per condividere lo stato tra due finestre aperte. Questo è l'ottavo di una serie di codelab complementari per il workshop sulle app web progressive. Il codelab precedente era Service Worker Includes. Questo è l'ultimo codelab della serie.
Obiettivi didattici
- Aggiungere un worker condiviso tra più finestre aperte
- Utilizzare Comlink per semplificare il lavoro con i lavoratori
Che cosa devi sapere
- JavaScript
Che cosa ti serve
- Un browser che supporti i web worker condivisi
2. Configurazione
Inizia clonando o scaricando il codice iniziale necessario per completare questo codelab:
Se cloni il repository, assicurati di trovarti nel ramo pwa06--working-with-workers
. Il file zip contiene anche il codice per questo ramo.
Questo codebase richiede Node.js 14 o versioni successive. Una volta disponibile il codice, esegui npm ci
dalla riga di comando nella cartella del codice per installare tutte le dipendenze necessarie. Poi, esegui npm start
per avviare il server di sviluppo per il codelab.
Il file README.md
del codice sorgente fornisce una spiegazione per tutti i file distribuiti. Inoltre, i seguenti sono i file esistenti chiave con cui lavorerai durante questo codelab:
File delle chiavi
js/preview.js
- File JavaScript della pagina di anteprimajs/main.js
- File JavaScript dell'applicazione principale
3. Scrivi un lavoratore
Al momento, la funzionalità di anteprima della tua web app mostra solo i contenuti più recenti al caricamento. Idealmente, dovrebbe mostrare un'anteprima dal vivo mentre l'utente digita. Ciò richiede la compilazione di quantità potenzialmente grandi di dati e il loro trasferimento tra due finestre aperte diverse. Per questo motivo, non vogliamo che venga eseguita sul thread principale di nessuna delle finestre aperte. Utilizziamo invece un web worker condiviso.
Per iniziare, crea un file js/worker.js
con il seguente codice:
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]);
Spiegazione
Questo codice configura una classe, chiamata Compiler
, che consente di impostare i contenuti e di chiamare gli abbonamenti una volta compilati i contenuti. Poiché si tratta di un worker condiviso, deve essere utilizzata una sola istanza di questa classe, quindi viene creata una nuova istanza di Compiler
. Poi, per rendere l'utilizzo di questa classe semplice dall'esterno del worker, viene utilizzato Comlink per esporre l'istanza del compilatore, consentendoci di utilizzare tutti i relativi metodi come se fossero dichiarati nel codice che la utilizza. Poiché si tratta di un worker condiviso anziché di un worker dedicato, deve essere esposto a tutte le connessioni.
4. Inviare contenuti al lavoratore
Ora che il worker è stato creato, dobbiamo inviargli i contenuti. Per farlo, aggiorna js/main.js
in modo che:
- Importa l'esportazione denominata
wrap
dacomlink
- Crea un nuovo Shared Worker di tipo modulo chiamato
worker
, imposta il tipo sumodule
e puntalo utilizzando il patternnew URL
(new URL('./worker.js', import.meta.url)
) - Crea una variabile
compiler
chewrap
ilworker.port
- Nella funzione di aggiornamento dell'editor (
editor.onUpdate
), dopo aver salvato i contenuti nel database, attendi il completamento dicompiler.set
, passando i contenuti
Spiegazione
Il wrapping di un'esportazione di Comlink consente di utilizzare elementi come i metodi di classe esposti come se non fossero condivisi oltre il limite di un worker, con l'eccezione che ora tutto è asincrono. Poiché si tratta di un worker condiviso anziché di un worker dedicato, Comlink deve eseguire il wrapping della porta del worker anziché del worker stesso. Ora, ogni volta che viene apportato un aggiornamento all'editor, i contenuti vengono inviati al worker per essere elaborati.
5. Aggiornare la pagina di anteprima
Il passaggio finale consiste nell'estrarre i contenuti compilati dal worker condiviso e inserirli nell'anteprima. La configurazione per farlo è in gran parte la stessa, ma poiché le funzioni non possono passare tra i limiti dei worker, è necessario utilizzare un proxy per la funzione. Comlink, ancora una volta, è qui per aiutarti. Aggiorna js/preview.js
per:
- Importa le esportazioni denominate
wrap
eproxy
dacomlink
- Crea e esegui il wrapping del worker condiviso come hai fatto in
js/main.js
- Chiama il metodo
subscribe
del compilatore con una funzione proxy che imposta la proprietàcompiled
dei dati in entrata sull'HTML interno dell'area di anteprima
Una volta fatto, apri l'anteprima, inizia a digitare nell'editor e divertiti a guardare il tuo markdown compilarsi e apparire in tempo reale nell'area di anteprima, il tutto senza bloccare il thread principale di nessuna delle pagine.
6. Complimenti!
Hai imparato a utilizzare un service worker condiviso per condividere lo stato tra più istanze PWA.