Panoramica dei worker

In che modo i web worker e i service worker possono migliorare le prestazioni del tuo sito e quando utilizzare un web worker rispetto a un service worker.

Andrew Guan
Andrew Guan
Demián Renzulli
Demián Renzulli

Questa panoramica spiega come i web worker e i service worker possono migliorare le prestazioni del tuo sito web e quando utilizzare un web worker rispetto a un service worker. Dai un'occhiata al resto di questa serie per scoprire pattern specifici di comunicazione tra finestre e service worker.

In che modo i worker possono migliorare il tuo sito web

Il browser utilizza un singolo thread (il thread principale) per eseguire tutto il codice JavaScript in una pagina web, nonché per svolgere attività come il rendering della pagina e la garbage collection. L'esecuzione di un codice JavaScript eccessivo può bloccare il thread principale, ritardando l'esecuzione di queste attività da parte del browser e causando un'esperienza utente scadente.

Nello sviluppo di applicazioni per iOS/Android, un pattern comune per garantire che il thread principale dell'app rimanga libero di rispondere agli eventi utente è l'offload delle operazioni su thread aggiuntivi. Infatti, nelle ultime versioni di Android, il blocco del thread principale per troppo tempo causa l'arresto anomalo dell'app.

Sul web, JavaScript è stato progettato attorno al concetto di un singolo thread e non dispone delle funzionalità necessarie per implementare un modello di multithreading come quello delle app, ad esempio la memoria condivisa.

Nonostante queste limitazioni, è possibile ottenere un pattern simile sul web utilizzando i worker per eseguire script in thread in background, consentendo loro di eseguire attività senza interferire con il thread principale. I worker sono un intero ambito JavaScript in esecuzione su un thread separato, senza memoria condivisa.

In questo post scoprirai due diversi tipi di worker (web worker e service worker), le loro somiglianze e differenze e i pattern più comuni per utilizzarli nei siti web di produzione.

Diagramma che mostra due collegamenti tra l'oggetto Window e un web worker e un service worker.

Web worker e service worker

Analogie

I web worker e i service worker sono due tipi di worker disponibili per i siti web. Hanno alcuni aspetti in comune:

  • Entrambi vengono eseguiti in un thread secondario, consentendo l'esecuzione del codice JavaScript senza bloccare il thread principale e l'interfaccia utente.
  • Non hanno accesso agli oggetti Window e Document, quindi non possono interagire direttamente con il DOM e hanno un accesso limitato alle API del browser.

Differenze

Si potrebbe pensare che la maggior parte delle cose che possono essere delegate a un web worker possa essere eseguita in un service worker e viceversa, ma esistono differenze importanti tra i due:

  • A differenza dei web worker, i service worker consentono di intercettare le richieste di rete (tramite l'evento fetch) e di ascoltare gli eventi dell'API Push in background (tramite l'evento push).
  • Una pagina può generare più web worker, ma un singolo service worker controlla tutte le schede attive nell'ambito con cui è stato registrato.
  • La durata del web worker è strettamente legata alla scheda a cui appartiene, mentre il ciclo di vita del service worker è indipendente da questa. Per questo motivo, la chiusura della scheda in cui è in esecuzione un web worker ne comporta l'interruzione, mentre un service worker può continuare a essere eseguito in background, anche quando il sito non ha schede attive aperte.

Casi d'uso

Le differenze tra i due tipi di worker suggeriscono in quali situazioni potrebbe essere preferibile utilizzare l'uno o l'altro:

I casi d'uso dei web worker sono più comunemente correlati all'offload del lavoro (come i calcoli complessi) a un thread secondario, per evitare di bloccare la UI.

Diagramma che mostra un link dall'oggetto Window a un web worker.
  • Esempio: il team che ha creato il videogioco PROXX voleva lasciare il thread principale il più libero possibile per gestire l'input dell'utente e le animazioni. Per raggiungere questo obiettivo, hanno utilizzato i web worker per eseguire la logica di gioco e la manutenzione dello stato su un thread separato.
Uno screenshot del videogioco PROXX.

Le attività dei service worker sono generalmente più correlate all'utilizzo come proxy di rete, alla gestione delle attività in background e ad aspetti come la memorizzazione nella cache e l'offline.

Uno screenshot del videogioco PROXX.

Esempio: in una PWA di podcast, potresti voler consentire agli utenti di scaricare puntate complete da ascoltare offline. A questo scopo, è possibile utilizzare un service worker e, in particolare, l'API Background Fetch. In questo modo, se l'utente chiude la scheda durante il download della puntata, l'attività non verrà interrotta.

Uno screenshot di una PWA di podcast.
La UI viene aggiornata per indicare l'avanzamento di un download (a sinistra). Grazie ai service worker, l'operazione può continuare a essere eseguita anche quando tutte le schede sono state chiuse (a destra).

Strumenti e librerie

La comunicazione tra finestra e worker può essere implementata utilizzando diverse API di livello inferiore. Fortunatamente, esistono librerie che astraggono questo processo, occupandosi dei casi d'uso più comuni. In questa sezione ne illustreremo due che si occupano rispettivamente della finestra per i web worker e i service worker: Comlink e Workbox.

Uno screenshot del videogioco PROXX.

Comlink è una piccola libreria RPC (1,6k) che si occupa di molti dettagli di base durante la creazione di siti web che utilizzano i web worker. È stato utilizzato in siti web come PROXX e Squoosh. Un riepilogo delle motivazioni e degli esempi di codice è disponibile qui.

Workbox

Workbox è una libreria molto utilizzata per creare siti web che utilizzano i service worker. Pacchettizza un insieme di best practice relative ad aspetti come la memorizzazione nella cache, l'offline, la sincronizzazione in background e così via. Il modulo workbox-window offre un modo pratico per scambiare messaggi tra il service worker e la pagina.

Passaggi successivi

Il resto di questa serie si concentra sui pattern per la comunicazione tra finestra e service worker:

  • Guida alla memorizzazione nella cache imperativa: chiamata di un service worker dalla pagina per memorizzare nella cache le risorse in anticipo (ad es. in scenari di precaricamento).
  • Trasmettere aggiornamenti: chiamare la pagina dal service worker per informare su aggiornamenti importanti (ad esempio, è disponibile una nuova versione del sito web).
  • Comunicazione bidirezionale: delega di un'attività a un service worker (ad esempio un download pesante) e aggiornamento della pagina sullo stato di avanzamento.

Per i pattern di comunicazione tra finestre e web worker, consulta: Utilizza i web worker per eseguire JavaScript all'esterno del thread principale del browser.