🔧 Web Worker in JavaScript: cosa sono, come si usano e perché servono (e differenze con Service Worker)
![]() |
In JavaScript, tutto il codice normalmente gira su un unico thread, chiamato main thread. Questo significa che operazioni pesanti, come calcoli complessi o elaborazione di dati, possono bloccare l'interfaccia utente e rendere l'app lenta o non responsiva.
Per evitare questo problema, esistono i Web Worker, una funzionalità del browser che permette di eseguire script in thread separati, senza bloccare l’interfaccia utente.
🚀 Cosa sono i Web Worker?
I Web Worker sono oggetti JavaScript che permettono di eseguire del codice in background, separato dal thread principale (quello della UI). Sono utilissimi per:
- Elaborazioni CPU-intensive
- Parsing di grossi file
- Manipolazioni complesse di dati
- Compressione/cripto di contenuti
- Operazioni asincrone non legate al DOM
❗ Importante: I Web Worker non hanno accesso diretto al DOM (document, window, alert, ecc.).
✍️ Come si usa un Web Worker?
1. Creare un file JS per il Worker
Per usare un Web Worker, la prima cosa da fare è creare un file JavaScript separato che conterrà il codice che verrà eseguito in background, cioè in un thread separato rispetto al main thread della pagina.
🔎 Perché serve un file separato?Il Web Worker viene caricato come uno script esterno, quindi il browser lo esegue in una sandbox isolata, senza accesso diretto al DOM, per motivi di sicurezza e prestazioni.
// worker.js
// Quando il worker riceve un messaggio dal main thread
self.onmessage = function(event) {
const number = event.data;
// Eseguiamo una funzione pesante (es. calcolo ricorsivo di Fibonacci)
const result = fibonacci(number);
// Rimandiamo il risultato al main thread
self.postMessage(result);
};
// Funzione di esempio: calcolo ricorsivo di Fibonacci
function fibonacci(n) {
if (n <= 1) return n;
return fibonacci(n - 1) + fibonacci(n - 2);
}
🧩 Spiegazione riga per riga:
-
self.onmessage: imposta un listener per ricevere dati dal main thread. L’oggetto self rappresenta il contesto globale del worker (simile a window nel main thread).
-
event.data: contiene il dato passato dal main thread (in questo caso, un numero).
-
fibonacci(n): esegue un calcolo matematico abbastanza pesante da giustificare l’uso di un worker.
-
self.postMessage(result): invia il risultato indietro al main thread, dove può essere gestito dall’interfaccia utente.
⚠️ Ricorda: il file worker.js deve trovarsi nello stesso dominio o rispettare le policy di CORS, altrimenti il browser lo bloccherà.
self.onmessage: imposta un listener per ricevere dati dal main thread. L’oggetto self rappresenta il contesto globale del worker (simile a window nel main thread).
event.data: contiene il dato passato dal main thread (in questo caso, un numero).
fibonacci(n): esegue un calcolo matematico abbastanza pesante da giustificare l’uso di un worker.
self.postMessage(result): invia il risultato indietro al main thread, dove può essere gestito dall’interfaccia utente.
⚠️ Ricorda: il file worker.js deve trovarsi nello stesso dominio o rispettare le policy di CORS, altrimenti il browser lo bloccherà.
2. Usare il Worker nel file principale
Una volta creato il file .js che definisce il comportamento del Web Worker (es. worker.js), è il momento di crearlo e utilizzarlo nel file principale della tua applicazione (es. main.js o all'interno di uno script HTML).
In questo contesto, il "main thread" è quello che gestisce la UI (interfaccia utente), il DOM, gli eventi dell’utente e tutte le attività che vediamo o con cui interagiamo.
✅ Esempio: main.js
// 1. Creiamo un nuovo Web Worker
const worker = new Worker('worker.js');
// 2. Ascoltiamo i messaggi provenienti dal worker
worker.onmessage = function(event) {
console.log('Risultato dal worker:', event.data);
// Qui potremmo aggiornare la UI, ad esempio:
document.getElementById('output').textContent = event.data;
};
// 3. Inviamo un dato al worker per iniziare il lavoro
worker.postMessage(40); // Ad esempio: calcola il 40° numero di Fibonacci
🧠 Perché è utile?
-
Senza il worker, calcolare
fibonacci(40)nel main thread potrebbe bloccare la pagina per vari secondi. -
Con un worker, l'elaborazione avviene in parallelo, e l'interfaccia utente rimane reattiva.
-
Usiamo
postMessage/onmessageperché i Web Worker non condividono memoria: la comunicazione avviene solo tramite messaggi asincroni.
🎯 Quando usare i Web Worker?
Usali quando un’operazione richiede molto tempo e potrebbe bloccare l'interfaccia utente. Alcuni casi pratici:
- Elaborazioni matematiche (es. calcolo di numeri primi, algoritmi di IA)
- Compressione o de-compressione di file (es. immagini, video)
- Parsing di JSON molto grandi
- Elaborazione di dati ricevuti via WebSocket o fetch
- Editor grafici o giochi complessi nel browser
🎯 Caso d’uso realistico
Supponi di avere una dashboard con visualizzazioni in tempo reale. Se il tuo codice deve analizzare un flusso di dati (es. da WebSocket o file CSV), puoi delegare il parsing e i calcoli a un Web Worker. Nel frattempo, il thread principale rimane libero per aggiornare grafici, gestire input dell’utente, ecc.
🤔 Web Worker vs Service Worker: se conosci i Service Worker, ecco come orientarti
Se hai familiarità con i Service Worker, potresti pensare che i Web Worker siano una variante simile o addirittura intercambiabile. Non è così.
Anche se entrambi sono eseguiti in thread separati, hanno scopi profondamente diversi. Ecco come comprenderli con un confronto concreto e concettuale:
🧭 Analogia semplice
| Concetto | Web Worker | Service Worker |
|---|---|---|
| 🎯 Scopo principale | Eseguire codice complesso in background | Intercettare richieste di rete e abilitare funzionalità offline |
| 📦 Contesto d’uso | Prestazioni, calcoli, elaborazione dati | Progressive Web App, caching, strategie di rete |
| 🕒 Durata di vita | Legato alla pagina o script principale | Vive anche senza pagina attiva (evento-driven) |
| 📞 Comunicazione | postMessage diretto con la pagina |
postMessage, fetch, push, sync |
| 🧱 Accesso al DOM | ❌ Mai | ❌ Mai |
| 🌐 Controllo della rete | ❌ No | ✅ Sì (intercetta richieste HTTP) |
🔍 Differenze chiave spiegate
1. Web Worker = potenza computazionale isolata
Usalo quando hai bisogno di spostare lavoro pesante lontano dal main thread. È come un assistente che prende un compito pesante e lo svolge in silenzio mentre tu continui a servire l’utente.
📌 Tipico uso di Web Worker:
-
Calcoli matematici
-
Compressione file
-
Parsing JSON enormi
-
Elaborazione immagini o video
2. Service Worker = proxy di rete + cache
È un middleware tra la tua web app e la rete. Serve a:
-
Rispondere a richieste fetch con cache personalizzata
-
Gestire contenuti offline
-
Abilitare notifiche push o background sync
📌 Tipico uso di Service Worker:
-
Offline-first experience
-
Aggiornamento automatico di asset statici
-
Push notifications
-
Caching dinamico e pre-caching
🤯 Cosa NON puoi fare con Web Worker (ma puoi con Service Worker)
-
Intercettare richieste
fetch -
Rispondere a eventi
install,activate,sync -
Mantenere uno stato tra sessioni anche se nessuna tab è aperta
🧠 Una metafora utile
-
Web Worker: è come un assistente matematico personale che lavora al tuo fianco, riceve dati e restituisce risultati.
-
Service Worker: è come un buttafuori alla porta della tua app che decide se una richiesta passa dalla rete, dalla cache o da qualche strategia personalizzata.
🧪 Quando usarli insieme?
Puoi usare entrambi nella stessa applicazione. Ad esempio:
Una PWA con un Service Worker che gestisce il caching offline, e un Web Worker che elabora localmente i dati ricevuti (es. filtra, analizza o aggrega un JSON di 10MB).
✅ In sintesi per chi arriva dai Service Worker
Se sei abituato ai Service Worker:
-
Pensa ai Web Worker come un modo per ottimizzare l’uso della CPU e rendere l’esperienza utente fluida.
-
Ricorda che non hanno nulla a che fare con la rete, ma tutto con l’elaborazione locale.
-
Usali quando hai operazioni che possono bloccare il thread principale, ma che non devono interagire col DOM o gestire richieste di rete.
⚠️ Limitazioni dei Web Worker
- Non puoi manipolare il DOM direttamente dal worker.
- La comunicazione è asincrona: usa
postMessageeonmessage. - Serve un file separato: non si può definire inline senza usare un Blob o data URI.
✅ Conclusione
I Web Worker sono strumenti potenti per migliorare le performance delle web app, evitando che operazioni complesse blocchino la UI. Non vanno confusi con i Service Worker, che hanno scopi diversi (cache, offline, notifiche).
Usali quando hai bisogno di parallelizzare il lavoro e lasciare reattiva l'interfaccia utente. Con una corretta architettura, i Web Worker possono fare la differenza tra un’app lenta e una fluida.
Follow me #techelopment
Official site: www.techelopment.it
facebook: Techelopment
instagram: @techelopment
X: techelopment
Bluesky: @techelopment
telegram: @techelopment_channel
whatsapp: Techelopment
youtube: @techelopment
