Hai mai avuto bisogno di eseguire codice nel browser che ha impiegato così tanto tempo per eseguire la tua applicazione che non rispondeva per un po'? Con i web worker HTML5, non avrai mai più bisogno di sperimentarlo di nuovo.

Gli operatori Web consentono di separare il codice di lunga durata ed eseguirlo indipendentemente da altro codice in esecuzione nella pagina. Ciò mantiene la tua interfaccia utente reattiva, anche durante operazioni complesse.

Cosa sono i Web Worker?

Tradizionalmente, JavaScript è un linguaggio a thread singolo. Ciò significa che nient'altro può essere eseguito mentre un pezzo di codice è in esecuzione. Ad esempio, se si dispone di codice che tenta di animare un elemento DOM, il codice che tenta di modificare una variabile deve attendere che l'animazione termini prima di poter essere eseguita.

I web worker sono file JavaScript che vengono eseguiti in un thread separato senza accesso diretto al DOM.

Un modo di pensare ai web worker è che sono pezzi di codice che richiedono molto tempo per essere eseguiti, quindi li dai al browser per eseguirli in background. Poiché quel codice è ora in esecuzione in background, non influisce sul JavaScript responsabile della tua pagina web.

instagram viewer

Come effetto collaterale, non può più interagire direttamente con il resto del codice, quindi i web worker non hanno accesso al DOM. Tuttavia, molte altre API del browser sono ancora disponibili, incluse le API WebSocket e Fetch.

Tuttavia, i web worker non sono del tutto isolati dal thread principale. Quando un lavoratore ha bisogno di comunicare con il thread principale, può inviare un messaggio e il thread principale può inviare il proprio messaggio in risposta.

Perché i Web Worker?

Prima dei web worker, l'unico modo per eseguire JavaScript che richiedeva molto tempo nel browser era:

  • Accetta che la pagina non risponda per un po'.
  • Rompi quel codice in blocchi asincroni.

Poiché una pagina che non risponde di solito è un'esperienza utente negativa, potresti optare per l'opzione asincrona. Scrivere il codice in questo modo significa dividerlo in parti più piccole che il browser può eseguire mentre non gestisce l'interfaccia utente. I pezzi devono essere abbastanza piccoli che, se l'interfaccia utente deve essere aggiornata, il browser può completare l'esecuzione del pezzo corrente e occuparsi dell'interfaccia utente.

I web worker sono stati aggiunti a HTML5 per offrire una soluzione migliore a questo problema. Invece di costringerti a essere creativo con codice asincrono, ti consentono di separare in modo pulito una funzione da eseguire nel proprio thread isolato.

Ciò ha reso più facile per gli sviluppatori scrivere tale codice e ha anche migliorato l'esperienza dell'utente.

Casi d'uso per i lavoratori Web

Qualsiasi applicazione che richieda molti calcoli sul lato client potrebbe trarre vantaggio dai web worker.

Supponiamo, ad esempio, che la tua applicazione desideri generare un rapporto sull'utilizzo e archivia tutti i dati sul client per motivi di privacy.

Per generare quel rapporto, l'applicazione web deve recuperare i dati, eseguire calcoli su di essi, organizzare i risultati e presentarli all'utente.

Se si tenta di farlo nel thread principale, l'utente non sarà completamente in grado di utilizzare l'applicazione mentre l'applicazione elabora i dati. Invece, puoi spostare parte o tutto quel codice in un web worker. Ciò consente all'utente di continuare a utilizzare l'applicazione durante l'esecuzione dei calcoli.

Come utilizzare i Web Worker in JavaScript

Il API Web Worker definisce come utilizzare i web worker. L'utilizzo di questa API implica la creazione di un oggetto Worker con il costruttore Worker in questo modo:

let newWorker = Worker('lavoratore.js');

Il Lavoratore costruttore accetta il nome di un file JavaScript come parametro ed esegue il file in un nuovo thread. Restituisce un oggetto Worker per consentire al thread principale di interagire con il thread di lavoro.

I lavoratori interagiscono con il thread principale inviando messaggi avanti e indietro. Tu usi il postMessaggio funzione per inviare eventi tra il lavoratore e il thread principale. Utilizzare il sul messaggio listener di eventi per ascoltare i messaggi dell'altra parte.

Ecco un esempio di codice. Innanzitutto, un thread principale potrebbe assomigliare a questo:

permettere lavoratore = nuovo Lavoratore('lavoratore.js')
worker.postMessage('Ehi!')

worker.onmessage = funzione(e) {
console.log('Il thread di lavoro dice', e.dati)
}

Questo thread principale crea un oggetto worker da worker.js, quindi invia un messaggio con worker.postMessage. Quindi definisce un listener di eventi, simile nel concetto a a Ascoltatore di eventi DOM. Un evento verrà attivato ogni volta che il lavoratore invia un messaggio al thread principale e il gestore registra il messaggio del lavoratore sulla console.

Il codice all'interno del lavoratore (worker.js) ha un lavoro:

sumessaggio = funzione(e) {
permettere messaggio = e.data;
console.log('Discussione principale ha detto', Messaggio);
postMessaggio('Ciao!')
}

Ascolta tutti i messaggi inviati dal thread principale, registra il messaggio sulla console e invia un messaggio di ritorno al thread principale.

I messaggi in questo esempio sono stati tutti stringhe, ma non è un requisito: puoi inviare quasi tutti i tipi di dati come messaggio.

Il tipo di lavoratori che hai visto finora sono chiamati lavoratori dedicati. Puoi accedervi solo dal file in cui li hai creati (gli sono dedicati). I lavoratori condivisi sono l'opposto: possono ricevere messaggi e inviare messaggi a più file. I lavoratori condivisi sono concettualmente gli stessi dei lavoratori dedicati, ma devi usarli in modo leggermente diverso.

Diamo un'occhiata a un esempio. Invece di utilizzare il costruttore Worker, ogni file che desidera utilizzare un worker condiviso deve creare un oggetto worker utilizzando lavoratore condiviso():

permettere lavoratore condiviso = nuovo SharedWorker('worker.js')

Le differenze però non si fermano qui. Affinché un file invii o riceva un messaggio da un lavoratore condiviso, deve farlo accedendo a porta oggetto, invece di farlo direttamente. Ecco come appare:

sharedWorker.port.postMessage('Ciao!')

sharedWorker.port.onMessage = funzione(e) {
console.log('Il lavoratore condiviso ha inviato', e.dati);
}

Devi usare anche l'oggetto port all'interno del lavoratore:

onconnect = funzione(e) {
cost porta = e.ports[0];

port.onmessage = funzione(e) {
console.log('Messaggio ricevuto', e.dati)
port.postMessage('Ciao!');
}
}

Il onconnect listener si attiva ogni volta che si verifica una connessione a una porta (quando un file sul messaggio il listener di eventi è impostato nel thread principale).

Quando ciò accade, il codice ottiene la porta a cui era appena connesso dall'evento di connessione e la memorizza in una variabile. Successivamente, il codice registra il sul messaggio listener sull'oggetto port. Il codice registra quindi il messaggio sulla console e utilizza la porta per inviare un messaggio al thread principale.

I Web Worker migliorano l'esperienza utente

I web worker sono thread JavaScript che consentono di eseguire in background parti di codice complesse e di lunga durata. Questo codice eviterà quindi di bloccare l'interfaccia utente. L'uso dei web worker semplifica notevolmente la scrittura di questo tipo di codice e migliora l'esperienza per l'utente dell'applicazione. Puoi creare web worker e interagire con loro utilizzando l'API web worker.