Offloading Work with JavaScript Web Workers

JavaScript is single-threaded on the main thread — a heavy computation blocks the entire UI, including scrolling and clicks. Web Workers run JavaScript on a genuinely separate thread to avoid exactly that.

// worker.js - runs on a separate thread, no DOM access
self.onmessage = (e) => {
    const result = heavyComputation(e.data);
    self.postMessage(result);
};

function heavyComputation(n) {
    let total = 0;
    for (let i = 0; i < n; i++) total += Math.sqrt(i);
    return total;
}
const worker = new Worker('worker.js');

worker.postMessage(100_000_000); // main thread stays responsive during this

worker.onmessage = (e) => {
    console.log('Result:', e.data);
};

Workers communicate with the main thread only via message passing (postMessage) — they can’t touch the DOM directly, which is the trade-off for genuine parallelism: real isolation instead of shared mutable state, avoiding the classic threading bugs found in languages with true shared-memory threads.