π§ Web Workers in JavaScript: What they are, How to use them, and Why they're needed (and differences with Service Workers)
![]() |
In JavaScript, all code normally runs on a single thread, called the main thread. This means that heavy operations, such as complex calculations or data processing, can block the user interface and make the app slow or unresponsive.
To avoid this problem, there are Web Workers, a browser feature that allows you to run scripts in separate threads, without blocking the user interface.
π What are Web Workers?
Web Workers are JavaScript objects that allow you to run code in the background, separate from the main thread (the UI one). They are very useful for:
- CPU-intensive processing
- Parsing large files
- Complex data manipulation
- Compressing/encrypting content
- Asynchronous operations not tied to the DOM
❗ Important: Web Workers do not have direct access to the DOM (document, window, alert, etc.).
✍️ How do I use a Web Worker?
1. Create a JS file for the Worker
To use a Web Worker, the first thing to do is create a separate JavaScript file that will contain the code that will run in the background, that is, in a separate thread from the main thread of the page.
π Why do we need a separate file?The Web Worker is loaded as an external script, so the browser runs it in an isolated sandbox, without direct access to the DOM, for security and performance reasons.
// worker.js
// When the worker receives a message from the main thread
self.onmessage = function(event) {
const number = event.data;
// Let's execute a heavy function (e.g. Fibonacci recursive calculation)
const result = fibonacci(number);
// Let's send the result back to the main thread
self.postMessage(result);
};
// Example function: Fibonacci recursive calculation
function fibonacci(n) {
if (n <= 1) return n;
return fibonacci(n - 1) + fibonacci(n - 2);
}
π§© Line by line explanation:
-
self.onmessage
: Set a listener to receive data from the main thread. The self
object represents the global context of the worker (similar to window
in the main thread).
-
event.data
: contains the data passed from the main thread (in this case, a number).
-
fibonacci(n)
: Performs a mathematical calculation heavy enough to justify using a worker.
-
self.postMessage(result)
: sends the result back to the main thread, where it can be handled by the UI.
⚠️ Remember: the worker.js
file must be in the same domain or respect CORS policies, otherwise the browser will will block.
self.onmessage
: Set a listener to receive data from the main thread. The self
object represents the global context of the worker (similar to window
in the main thread).
event.data
: contains the data passed from the main thread (in this case, a number).
fibonacci(n)
: Performs a mathematical calculation heavy enough to justify using a worker.
self.postMessage(result)
: sends the result back to the main thread, where it can be handled by the UI.
⚠️ Remember: the worker.js
file must be in the same domain or respect CORS policies, otherwise the browser will will block.
2. Using the Worker in the main file
Once you have created the .js
file that defines the behavior of the Web Worker (e.g. worker.js
), it is time to create and use it in the main file of your application (e.g. main.js
or inside an HTML script).
In this context, the "main thread" is what handles the UI (user interface), DOM, user events and all the activities we see or interact with.
✅ Example: main.js
// 1. Create a new Web Worker
const worker = new Worker('worker.js');
// 2. Listen for messages from the worker
worker.onmessage = function(event) {
console.log('Result from worker:', event.data);
// Here we could update the UI, for example:
document.getElementById('output').textContent = event.data;
};
// 3. Send some data to the worker to start the worker
worker.postMessage(40); // For example: calculate the 40th Fibonacci number
π§ Why is it useful?
-
Without the worker, calculating
fibonacci(40)
in the main thread could block the page for several seconds. -
With a worker, processing happens in parallel, and the UI remains responsive.
-
We use
postMessage
/onmessage
because Web Workers do not share memory: communication happens only via asynchronous messages.
π― When to use Web Workers?
Use them when an operation takes a long time and could block the user interface. Some practical cases:
- Mathematical calculations (e.g. prime number calculations, AI algorithms)
- Compression or decompression of files (e.g. images, videos)
- Parsing very large JSON
- Processing data received via WebSocket or fetch
- Complex graphics editors or games in the browser
π― Realistic use case
Suppose you have a dashboard with real-time visualizations. If your code needs to analyze a data stream (e.g. from WebSockets or CSV files), you can delegate parsing and calculations to a Web Worker. In the meantime, the main thread remains free to update graphs, handle user input, etc.
π€ Web Worker vs Service Worker: If you're familiar with Service Workers, here's how to navigate it
If you're familiar with Service Workers, you might think that Web Workers are a similar or even interchangeable variant. That's not the case.
Even though both are executing in separate threads, have deeply different purposes. Here's how to understand them with a concrete and conceptual comparison:
π§ Simple analogy
Concept | Web Worker | Service Worker |
---|---|---|
π― Main purpose | Execute complex code in the background | Intercept network requests and enable functionalityoffline |
π¦ Context of use | Performance, calculations, data processing | Progressive Web App, caching, network strategies |
π Lifetime | Tied to the main page or script | Also lives without an active page (event-driven) |
π Communication | postMessage directly with the page |
postMessage , fetch , push , sync |
π§± Access to the DOM | ❌ Never | ❌ Never |
π Network control | ❌ No | ✅ Yes (intercept HTTP requests) |
π Key differences explained
1. Web Worker = Isolated Computational Power
Use it when you need to move heavy work away from the main thread. It's like an assistant that takes a heavy task and does it silently while you continue serving the user.
π Typical Web Worker usage:
-
Mathematical calculations
-
File compression
-
JSON parsing huge
-
Image or video processing
2. Service Worker = network proxy + cache
It is a middleware between your web app and the network. It is used to:
-
Respond to fetch requests with custom cache
-
Manage offline content
-
Enable push notifications or background sync
π Typical use of Service Worker:
-
Offline-first experience
-
Automatically updating static assets
-
Push notifications
-
Dynamic Caching and Pre-caching
π€― What you can NOT do with Web Workers (but you can with Service Workers)
-
Intercepting
fetch requests
-
Responding to events
install
,activate
,sync
-
Maintain state between sessions even if no tab is open
π§ A useful metaphor
-
Web Worker: It's like a personal math assistant that works alongside you, takes in data, and returns results.
-
Service Worker: It's like a bouncer at your app's door that decides whether a request goes through the network, cache, or some custom strategy.
π§ͺ When to use them together?
You can use both in the same application. For example:
A PWA with a Service Worker che handles offline caching, and a Web Worker that processes the received data locally (e.g. filters, parses or aggregates a 10MB JSON).
✅ In summary for those coming from Service Workers
If you are used to Service Workers:
-
Think about Web Worker as a way to optimize CPU usage and make the user experience smooth.
-
Remember that they have nothing to do with networking, but everything to do with local processing.
-
Use them when you have operations that can block the main thread, but don't need to interact with the DOM or handle requests for network.
⚠️ Limitations of Web Workers
- You cannot manipulate the DOM directly from the worker.
- Communication is asynchronous: use
postMessage
andonmessage
. - You need a separate file: you cannot define inline without using a Blob or data URI.
✅ Conclusion
Web Workers are powerful tools to improve the performance of web apps, preventing complex operations from blocking the UI. They should not be confused with Service Workers, which have different purposes (cache, offline, notifications).
Use them when you need to parallelize work and keep the UI responsive. With the right architecture, Web Workers can make the difference between a slow app and a smooth one.
Follow me #techelopment
Official site: www.techelopment.it
facebook: Techelopment
instagram: @techelopment
X: techelopment
Bluesky: @techelopment
telegram: @techelopment_channel
whatsapp: Techelopment
youtube: @techelopment