Skip to content
Plurafy

Web Workers and Threading

Running JavaScript in background threads

Offload CPU-intensive tasks to background threads without blocking the UI.

Web Workers allow long-running scripts to run in background threads without freezing the UI.

main.js
const worker = new Worker('worker.js');
// Send message to worker
worker.postMessage({ data: [1, 2, 3, 4, 5] });
// Receive result from worker
worker.onmessage = (event) => {
console.log('Result:', event.data);
};
// Handle errors
worker.onerror = (error) => {
console.error('Worker error:', error.message);
};
// Terminate worker
worker.terminate();
worker.js
self.onmessage = (event) => {
const { data } = event;
const result = data.map(n => n * n);
self.postMessage({ result });
};
// Multiple pages sharing one worker
const sharedWorker = new SharedWorker('shared-worker.js');
sharedWorker.port.start();
sharedWorker.port.postMessage({ message: 'hello' });
sharedWorker.port.onmessage = (event) => {
console.log('From worker:', event.data);
};
// Heavy computation
const worker = new Worker('compute.js');
// Image processing
const imageWorker = new Worker('image-processor.js');
imageWorker.postMessage({ imageData, width, height });
// Data parsing
const parserWorker = new Worker('parser.js');
parserWorker.postMessage({ json: largeJson });
// Background polling
const pollerWorker = new Worker('poller.js');
pollerWorker.postMessage({ endpoint: '/api/updates', interval: 5000 });
// Transfer ownership instead of copying
const arrayBuffer = new ArrayBuffer(1024);
// This transfers the buffer (doesn't copy)
worker.postMessage({ buffer: arrayBuffer }, [arrayBuffer]);
// arrayBuffer is now empty in main thread
// Worker has full ownership
// Workers have limited access
// ✅ Can use:
// - postMessage
// - setTimeout, setInterval
// - navigator object
// - XMLHttpRequest, fetch
// - Worker constructor
// ❌ Cannot use:
// - DOM manipulation
// - window object properties
// - alert, confirm
// - document object
// Share data via messages
worker.postMessage({ type: 'update', data: newData });
main.js
function processLargeDataset(data) {
return new Promise((resolve, reject) => {
const worker = new Worker('processor.js');
worker.postMessage({ data });
worker.onmessage = (event) => {
worker.terminate();
resolve(event.data);
};
worker.onerror = (error) => {
worker.terminate();
reject(error);
};
});
}
// Use it
processLargeDataset(largeArray).then(result => {
console.log('Processed:', result);
});
// processor.js
self.onmessage = async (event) => {
const { data } = event;
// Heavy processing
const result = await process(data);
self.postMessage(result);
};