What are Web Workers for?
By FrontendPro Editorial Team Updated 9/26/2026
Answer
A Web Worker runs JavaScript on a separate thread, so heavy computation does not freeze the page. It is the only real answer when work genuinely takes a long time — async does not help, because an async function still occupies the main thread while it computes.
// main.js
const worker = new Worker("/worker.js", { type: "module" });
worker.postMessage({ rows: bigDataset });
worker.onmessage = (e) => render(e.data);
// worker.js
self.onmessage = (e) => {
const result = expensiveAnalysis(e.data.rows);
self.postMessage(result);
};
The UI stays responsive throughout — scrolling, animation and clicks keep working.
What a worker cannot do
No DOM, no window, no document. A worker can compute and fetch, but the main thread must apply the results. It does have fetch, WebSocket, IndexedDB, crypto and timers.
Communication has a cost
Messages are copied with structured clone, so passing a very large object is itself expensive. For big binary data, transfer ownership instead of copying:
worker.postMessage(buffer, [buffer]); // zero-copy; buffer is unusable here after
This is why a worker is not automatically faster. Moving a 5 ms task into one usually makes things slower once you count serialisation and thread startup.
When it is worth it
Parsing or transforming a large file, image and video processing, cryptography, search indexing, running a WASM module, and anything that would otherwise produce a long task over ~50 ms. Libraries like Comlink hide the message plumbing behind ordinary function calls.
The other worker types
A Service Worker is a different thing — a network proxy for caching and offline support, not a compute thread. A SharedWorker is one worker shared by several tabs of the same origin.
