← Back to Chapters

JavaScript Web Workers

⚙️ JavaScript Web Workers

⚡ Quick Overview

Web Workers let you run JavaScript in background threads, separate from the main UI thread. This helps you perform heavy or CPU-intensive tasks without blocking the page or making it feel slow and unresponsive.

They are ideal for tasks like data processing, image manipulation, and real-time calculations, where performance and responsiveness are both important.

? Key Concepts

  • Background thread: Web Workers run in a separate background thread.
  • Main thread: Handles the DOM, rendering, and user interactions.
  • Message-based communication: Data is passed using postMessage() and received with onmessage.
  • No direct DOM access: Workers cannot directly read or update the DOM.
  • Long-running tasks: Perfect for heavy computations that would normally freeze the UI.
  • Lifecycle control: You can explicitly terminate workers when they are no longer needed.

? Syntax & Theory

? Creating a Worker

A worker is created by instantiating the Worker constructor and passing the URL of the worker script file:

? View Code Example
// main.js
const worker = new Worker("worker.js");

? Communicating with a Worker

Use postMessage() to send data to the worker and onmessage to receive data back from the worker.

  • worker.postMessage(data) — send data from main thread to worker.
  • onmessage = (event) => {"{"} ... {"}"} — handle incoming messages.

? Code Examples

? Example: Send and Receive Data

This example shows a main script sending a number to the worker. The worker doubles the value and sends the result back.

? View Code Example (main.js & worker.js)
// main.js
const worker = new Worker("worker.js");

// Send data to the worker
worker.postMessage({ num: 10 });

// Receive data from the worker
worker.onmessage = function(event) {
  console.log("Result from worker:", event.data);
};

// Optional: handle errors
worker.onerror = function(error) {
  console.error("Worker error:", error.message);
};

// worker.js
onmessage = function(event) {
  const input = event.data.num;
  const result = input * 2;        // heavy computation placeholder
  postMessage(result);             // send result back to main thread
};

? Example: Terminating a Worker

Workers do not automatically stop when your task is done. You should terminate them to free up memory and system resources.

? View Termination Example
// main.js
const worker = new Worker("worker.js");

// After some time or when the task is done
worker.terminate();               // stops the worker from the main thread

// worker.js
onmessage = function(event) {
  // do some work
  // ...
  // stop the worker from inside the worker file
  close();
};

? Live Output & Explanation

? What Happens Step-by-Step?

  1. The main script creates a worker using new Worker("worker.js").
  2. The main script sends data to the worker using worker.postMessage().
  3. The worker receives the message inside its onmessage handler.
  4. The worker performs the heavy computation (for example, doubling a number).
  5. The worker sends the result back using postMessage().
  6. The main script receives the result inside worker.onmessage and updates the UI or logs it.
  7. Once work is finished, the worker is terminated using worker.terminate() or close().

Because the work happens in a background thread, the main UI thread remains smooth: scrolling, clicking buttons, and typing input stay responsive.

? Helpful Tips

  • Do not try to access or manipulate DOM elements directly inside a worker.
  • Use Web Workers only for heavier computations, not simple UI logic.
  • Keep messages small and simple; passing very large objects can be slow.
  • Use structuredClone() or transferable objects (like ArrayBuffer) for complex data when needed.
  • Always terminate workers after their job is done to avoid memory leaks.

? Practice Tasks

  • Create a Web Worker that calculates Fibonacci numbers for large inputs without freezing the UI.
  • Send progress updates from the worker back to the main script (for example, every 1000 iterations) and display them in the console or on the page.
  • Terminate the worker automatically after the computation completes to free resources.
  • Experiment with sending different types of data (numbers, strings, objects) between the main thread and the worker.