One of the core characteristics of JavaScript in the browser is that the main execution environment is usually single-threaded.
That means if the main thread is busy doing expensive work, such as large text parsing, image processing, or heavy computation, the page can lag at the same time.
That is why browsers provide Web Worker.
Its purpose is simple:
If heavy work runs on the main thread:
Web Worker helps by moving that expensive work away from the UI thread.
You can think of a Web Worker as:
a background JavaScript runtime environment provided by the browser
It runs separately from the main thread and communicates through postMessage.
const worker = new Worker("./worker.js");worker.postMessage({ type: "start", payload: 1000000 });self.onmessage = (event) => { const { payload } = event.data; const result = payload * 2; self.postMessage({ type: "done", result });};worker.onmessage = (event) => { console.log(event.data.result);};Web Worker is a strong fit for:
Workers cannot directly access the DOM.
If the task is too small, the messaging overhead may outweigh the benefit.
If the code relies heavily on browser UI state, it may not be a good worker candidate.
Web Worker is not just “more async”.
Normal async operations like fetch are already asynchronous, but their follow-up processing may still happen on the main thread.
Web Worker solves a different problem:
A typical scenario:
In that case, the main thread can pass raw data to a worker, and the worker sends processed results back.
Large message payloads can still be expensive.
type field to messagesworker.postMessage({ type: "parse", payload });This makes message handling more maintainable.
requestIdIf multiple requests can run at once, use IDs to match responses.
Always think about failure cases:
worker.onerror = (error) => { console.error(error);};Consider it when:
Web Worker is one of the most practical tools for keeping browser apps responsive during heavy work.
Its core value is not just asynchronous execution. Its real value is: