Skip to content

JavaScript Tutorial Web APIs

Introduction to Web Workers

Lesson 215 of 258 2 min read By Deepak Paswan Updated Oct 4, 2026

JavaScript runs on one main thread, and a long calculation freezes the page: no clicks, no scrolling, no animation. A Web Worker runs code in a separate background thread, so the page stays responsive.

> Workers need separate files (or blob URLs) and a real page, so this lesson shows the code to use in your own project.

The two files

worker.js
JS
// runs in the background thread
self.addEventListener("message", event => {
  const n = event.data;

  let sum = 0;
  for (let i = 0; i <= n; i++) sum += i;     // heavy work

  self.postMessage(sum);                      // send the result back
});
main.js
JS
const worker = new Worker("worker.js");

worker.addEventListener("message", event => {
  console.log("Result from the worker:", event.data);
});

worker.postMessage(1_000_000_000);            // send work
console.log("The page stays responsive meanwhile");

Communication is by messages (postMessage and the message event). Data is copied between threads with the structured clone algorithm (the same one structuredClone() uses), so you cannot share live objects or functions.

What a worker cannot do

  • No DOM. There is no document or window in a worker. It cannot change the page directly. It sends results to the main thread, which updates the page.
  • No access to the main thread’s variables.

It can use: fetch, timers, IndexedDB, WebSocket, importScripts() or module imports, console, and most computation.

Module workers

script.js
JS
const worker = new Worker("worker.js", { type: "module" });

Lets the worker use import and export.

Errors and stopping

script.js
JS
worker.addEventListener("error", event => console.error("Worker error:", event.message));
worker.terminate();      // stop it from the main thread
// inside a worker: self.close();

Transferring big data

Large buffers can be transferred instead of copied, which is instant:

script.js
JS
const buffer = new ArrayBuffer(10_000_000);
worker.postMessage(buffer, [buffer]);     // after this, `buffer` is no longer usable here

When to use workers

Use a worker for CPU-heavy work: parsing big files, image processing, complex calculations, compressing, searching a large data set.

Do not use one for waiting: fetch and timers do not block the main thread, so a worker adds nothing.

Other kinds of workers

  • Service Workers: sit between the page and the network (offline support, push notifications).
  • Shared Workers: shared by several tabs.
  • Worklets: specialised, for audio and painting.

Costs

Starting a worker has a cost, and messaging adds overhead. For small tasks, a worker is slower than just doing the work. Measure first (Performance).

lightbulb
The mental picture
The main thread is a shop counter that must always be free to serve customers. A worker is a back room where long jobs happen, and it sends a note when they are done.