Web Workers & Multithreading in JS0%

Web Workers & Multithreading in JS

Beginner12 min read•Updated: Jul 11, 2026
Study Materials

Web Workers & Multithreading in Modern JavaScript

While JavaScript is famous for its single-threaded Event Loop, modern browsers provide true hardware-level multithreading via the Web Workers API. Web Workers run scripts in background threads, enabling CPU-intensive operations (image processing, cryptographic hashing, 3D physics, big-data filtering) without blocking the main UI thread.


1. Main Thread vs. Worker Thread

Output
┌──────────────────────────────────────────────┐
│ MAIN THREAD │
│ • Manages DOM, Layout, CSS, and UI events │
│ • Freezes if heavy calculation runs here! │
└──────────────────────┬───────────────────────┘
│ postMessage(data)
▼
┌──────────────────────────────────────────────┐
│ DEDICATED WEB WORKER THREAD │
│ • Runs in true parallel operating thread │
│ • NO direct access to DOM or window │
│ • Has its own global: self / DedicatedWorker│
└──────────────────────────────────────────────┘

What Workers CANNOT Access:

  • The DOM (document.querySelector, window)
  • parent object
  • Local DOM nodes

What Workers CAN Access:

  • fetch() and XMLHttpRequest
  • IndexedDB
  • WebSockets
  • crypto.subtle
  • setTimeout, setInterval

2. Spawning and Communicating with a Worker

1. The Worker Script (worker.js)

JavaScript
// worker.js: Runs in isolated background thread
self.addEventListener('message', (event) => {
const { numbers } = event.data;
console.log('[Worker] Received array of size:', numbers.length);
 
// Intensive CPU computation (e.g. prime number filtering)
const primes = numbers.filter(isPrime);
 
// Send results back to main thread
self.postMessage({ primes, count: primes.length });
});
 
function isPrime(num) {
if (num <= 1) return false;
for (let i = 2; i <= Math.sqrt(num); i++) {
if (num % i === 0) return false;
}
return true;
}

2. The Main Script (app.js)

JavaScript
// app.js: Spawns worker from main thread
const worker = new Worker('worker.js');
 
// Listen for results
worker.addEventListener('message', (event) => {
console.log('[Main] Primes computed in background:', event.data.count);
hideSpinner();
});
 
// Listen for worker errors
worker.addEventListener('error', (err) => {
console.error('[Main] Worker error:', err.message);
});
 
// Dispatch heavy workload to background thread
const dataPayload = Array.from({ length: 5000000 }, (_, i) => i + 1);
worker.postMessage({ numbers: dataPayload });
 
// Terminate worker when no longer needed
// worker.terminate();

3. High-Performance Zero-Copy: Transferable Objects

By default, data passed via postMessage() is cloned using the Structured Clone Algorithm (deep copy), which can be slow for 500MB video buffers or typed arrays.

Transferable Objects transfer memory ownership instantly with zero copy ($O(1)$ transfer time). The sender relinquishes ownership:

JavaScript
const buffer = new ArrayBuffer(1024 * 1024 * 64); // 64MB Buffer
 
// Transfer ownership to worker (Zero-copy transfer!)
worker.postMessage({ buffer }, [buffer]);
 
// In main thread: buffer.byteLength is now 0! It has been moved to worker.
console.log('Buffer transferred:', buffer.byteLength === 0); // true!

4. Modern Inline Workers with Blob URLs

When building components with Vite or Webpack, you can create Workers dynamically from string literals:

JavaScript
const workerCode = `
self.onmessage = (e) => {
self.postMessage(e.data * 2);
};
`;
 
const blob = new Blob([workerCode], { type: 'application/javascript' });
const workerUrl = URL.createObjectURL(blob);
const inlineWorker = new Worker(workerUrl);

Interactive Quiz

Practice Quiz

Question 1
What is the primary advantage of offloading heavy computations to a Web Worker?
Question 2
Can a Web Worker directly manipulate DOM elements via document.getElementById()?
Question 3
What method communicates data between the main thread and a Web Worker?
Question 4
What happens to an ArrayBuffer when it is sent to a Worker as a Transferable Object?
Question 5
How do you immediately terminate an active Web Worker from the main thread?
Next Lesson

Custom Error Hierarchies & Prototypes

Continue learning with hands-on practice, examples, and exercises in the upcoming topic.

Practice Quiz

Test your understanding of this lesson with 5 questions. Each question has one correct answer.

PrevNext