patternjavascriptModerate
Web Workers for heavy computation to keep the main thread free
Viewed 0 times
Web WorkerpostMessageoffloadmain threadbackground threadTransferableSharedArrayBuffer
Problem
CPU-intensive tasks (large data parsing, image processing, encryption, sorting huge arrays) run on the main thread and block rendering and user interactions for their entire duration.
Solution
Move the computation to a Web Worker. Communicate via postMessage/onmessage.
// worker.js
self.onmessage = function(event) {
const { data, type } = event.data;
if (type === 'PROCESS') {
const result = heavyComputation(data);
self.postMessage({ type: 'RESULT', result });
}
};
// main.js
const worker = new Worker(new URL('./worker.js', import.meta.url));
worker.postMessage({ type: 'PROCESS', data: largeArray });
worker.onmessage = (event) => {
if (event.data.type === 'RESULT') {
updateUI(event.data.result);
}
};
// worker.js
self.onmessage = function(event) {
const { data, type } = event.data;
if (type === 'PROCESS') {
const result = heavyComputation(data);
self.postMessage({ type: 'RESULT', result });
}
};
// main.js
const worker = new Worker(new URL('./worker.js', import.meta.url));
worker.postMessage({ type: 'PROCESS', data: largeArray });
worker.onmessage = (event) => {
if (event.data.type === 'RESULT') {
updateUI(event.data.result);
}
};
Why
Web Workers run in a separate thread with their own event loop. The main thread remains responsive during the computation. Structured clone algorithm copies data between threads; use Transferable objects (ArrayBuffer) for zero-copy transfer of large data.
Gotchas
- Workers cannot access the DOM — they only communicate via postMessage
- Transferring a large ArrayBuffer with transfer option is zero-copy: worker.postMessage(buffer, [buffer])
- SharedArrayBuffer requires Cross-Origin-Opener-Policy and Cross-Origin-Embedder-Policy headers
- Worker startup has overhead (~1-5ms) — reuse workers rather than creating new ones per task
Code Snippets
Transferable ArrayBuffer for zero-copy worker communication
// Zero-copy transfer of large buffer
const buffer = new ArrayBuffer(1024 * 1024 * 10); // 10MB
// Transfer ownership to worker — buffer is detached in main thread
worker.postMessage({ buffer }, [buffer]);Context
When a synchronous computation takes more than ~50ms and cannot be broken into smaller async chunks
Revisions (0)
No revisions yet.