What are Web Workers?
Web Workers let you run JavaScript in a background thread, separate from the main UI thread. This means heavy computations won't freeze the page. The worker runs in its own scope — it can't access the DOM, but it can make network requests and use IndexedDB.
// main.js
const worker = new Worker("worker.js");
worker.postMessage({ data: largeArray });
worker.onmessage = (event) => {
console.log("Result:", event.data);
};
// worker.js
self.onmessage = (event) => {
const result = processLargeData(event.data);
self.postMessage(result);
};
When to Use Web Workers
Use workers for CPU-intensive tasks like image processing, complex calculations, data sorting, or parsing large JSON files. If a task takes more than ~16ms, it will cause jank on the main thread.
// worker.js — sorting a huge array
self.onmessage = (event) => {
const { array } = event.data;
// This might take a while
const sorted = array.sort((a, b) => a - b);
self.postMessage(sorted);
};
Communication via postMessage
Workers and the main thread communicate through messages. Data is copied (structured clone), not shared. You can also transfer binary data like ArrayBuffers for better performance.
// Transfer an ArrayBuffer to the worker
const buffer = new ArrayBuffer(1024 * 1024);
worker.postMessage({ buffer }, [buffer]);
// buffer is now neutered (empty) on the main thread
Try it Yourself →
Handling Errors
Workers can throw errors just like main thread code. Always set up error handlers to catch problems in the worker.
const worker = new Worker("worker.js");
worker.onerror = (error) => {
console.error("Worker error:", error.message);
};
Summary
Web Workers keep your UI responsive by offloading heavy work to background threads. They communicate via postMessage and can't access the DOM. Use them for any CPU-intensive task.