Bitlyst

Web Workers Explained for Frontend Developers

Web Workers Explained for Frontend Developers

JavaScript in the browser is single-threaded โ€” but modern web apps often need to do heavy work without freezing the UI.

Thatโ€™s where Web Workers come in.

Web Workers allow real parallel execution of JavaScript code in the browser.


๐Ÿง  The Problem Web Workers Solve

Without workers, heavy computations block the main thread:

button.onclick = () => {
  heavyCalculation(); // โŒ UI freezes
};

Symptoms:

  • Scrolling jank
  • Input lag
  • โ€œPage is unresponsiveโ€ warnings

Why? ๐Ÿ‘‰ The main thread is responsible for:

  • Rendering
  • User input
  • Running JS

Block it, and everything stops.


๐Ÿš€ What Is a Web Worker?

A Web Worker is:

  • A separate JavaScript thread
  • Running in parallel to the main thread
  • With its own event loop
  • No access to the DOM

This is true parallelism, not just async I/O.


๐Ÿงฑ Main Thread vs Worker

CapabilityMain ThreadWeb Worker
Run JSโœ…โœ…
DOM accessโœ…โŒ
Parallel executionโŒโœ…
Network requestsโœ…โœ…
Timersโœ…โœ…
Blocking UIโŒโŒ (isolated)

โš™๏ธ Basic Example

worker.js

self.onmessage = (event) => {
  const result = event.data * 2;
  self.postMessage(result);
};

main.js

const worker = new Worker("worker.js");

worker.postMessage(10);

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

Flow:

Main Thread โ†’ postMessage โ†’ Worker
Worker โ†’ postMessage โ†’ Main Thread

๐Ÿ” Communication Model

Workers communicate via message passing, not shared memory (by default).

  • Data is copied using the structured clone algorithm
  • No race conditions
  • No shared mutable state
worker.postMessage({ numbers: [1, 2, 3] });

โšก Transferable Objects (Advanced)

To avoid copying large data:

worker.postMessage(buffer, [buffer]);
  • Ownership transfers to the worker
  • Zero-copy
  • Original buffer becomes unusable on main thread

Great for:

  • Image processing
  • Audio buffers
  • Large datasets

๐Ÿงฉ Real-World Use Cases

โœ… CPU-heavy work:

  • Data processing
  • Encryption / hashing
  • Image resizing
  • PDF parsing
  • Chart calculations

โŒ Not for:

  • DOM updates
  • Simple async calls
  • Lightweight logic

โš›๏ธ Using Web Workers with React

useEffect(() => {
  const worker = new Worker(new URL("./worker.js", import.meta.url));

  worker.postMessage(data);

  worker.onmessage = (e) => {
    setResult(e.data);
  };

  return () => worker.terminate();
}, []);

Best practice:

  • Create workers lazily
  • Terminate when not needed
  • Keep worker logic pure

๐Ÿง  Web Workers vs async/await

Featureasync/awaitWeb Worker
Parallel JSโŒโœ…
I/O concurrencyโœ…โœ…
CPU offloadingโŒโœ…
DOM accessโœ…โŒ

๐Ÿงช Types of Workers

TypeDescription
Dedicated WorkerOne page โ†” one worker
Shared WorkerMultiple tabs share
Service WorkerNetwork proxy / offline

This article focuses on Dedicated Workers.


โš ๏ธ Common Mistakes

โŒ Doing DOM work in workers
โŒ Spawning too many workers
โŒ Sending huge objects without transferables
โŒ Forgetting to terminate workers


๐Ÿง  Mental Model

  • Main thread = UI brain
  • Worker = background CPU
  • Messages = mailbox

Workers do the heavy lifting. Main thread stays smooth.


โœ… Summary

ConceptMeaning
Web WorkerBackground JS thread
ParallelismReal CPU parallel execution
CommunicationpostMessage
DOM accessNot allowed
Best useHeavy computation

โœจ Final Takeaway

If async/await gives you concurrency, Web Workers give you parallelism.
Use them when performance truly matters.


Suggested follow-ups

  • SharedArrayBuffer & Atomics
  • Worker Pools
  • OffscreenCanvas

How did you like this post?

๐Ÿ‘0
โค๏ธ0
๐Ÿ”ฅ0
๐Ÿค”0
๐Ÿ˜ฎ0