JavaScript is single-threaded โ a heavy loop freezes clicks, scrolling, everything. Workers are real background threads for exactly this.
The pattern
// main.js
const worker = new Worker("crunch.js");
worker.postMessage({ numbers: bigArray });
worker.onmessage = (e) => showResult(e.data); // UI never froze
// crunch.js
self.onmessage = (e) => {
const result = heavyComputation(e.data.numbers); // blocks THIS thread only
self.postMessage(result);
};The rules
- Workers have no DOM access โ pure computation only; send results back via postMessage
- Data is copied (structured clone), not shared โ design messages accordingly
- Inline workers via Blob URLs โ no separate file needed
Real example: our DSA judge
The practice judge runs YOUR submitted code in a Blob-URL worker: an infinite loop in your solution can't freeze the page, and worker.terminate() after 3 seconds implements Time Limit Exceeded. Sandboxing + responsiveness in one API.
When to reach for one
Parsing huge files, image processing, crypto, running untrusted code, anything >50ms of pure CPU. Async/await does NOT help with CPU work โ that's the interview distinction: async handles waiting, workers handle computing.
โ All Articles