JavaScript runs on a single main thread by default. When performing heavy computations (like processing image pixels or parsing complex data structures), the thread blocks, causing the user interface to freeze.
Web Workers resolve this bottleneck by executing tasks in background threads.
1. Web Worker Execution Model
Web Workers run in an isolated execution thread with its own scope. They communicate with the main thread using an event-driven postMessage API:
- Isolation: Web Workers do not have access to the DOM,
window, ordocumentvariables. They cannot update the UI directly. - Message Pipeline: Data is serialized and passed between threads through messages.
2. Creating a Web Worker
To spawn a worker thread, instantiate the worker class and register message handlers:
// main.js - Spawning the worker
const worker = new Worker('heavy-task.js');
worker.postMessage({ data: imagePixels });
worker.onmessage = (event) => {
console.log("Processed output data:", event.data.result);
};
In the worker script, handle incoming messages and return the results:
// heavy-task.js - Worker execution thread
self.onmessage = (event) => {
const result = performComputation(event.data.data);
self.postMessage({ result });
};
Offloading expensive calculations to worker threads keeps the main thread clear to process UI layout updates and animations.