JavaScript Web Workers
Until now, all examples in this tutorial run on the browser's main thread.
Asynchronous programming keeps applications responsive while waiting for:
- Timers
- User input
- Network requests
However, long-running calculations can still block the main thread and make a page unresponsive.
Web Workers solve this by running JavaScript in a separate thread.
Why Web Workers?
JavaScript normally executes one task at a time.
If a task takes a long time to finish, the browser cannot respond to user input until the task has completed.
This can make a page appear frozen.
The page becomes unresponsive until the calculation finishes.
Example
A long-running calculation freezes the page.
function calculate() {
let total = 0;
for (let i = 0; i < 5e9; i++) {
total += i;
}
return total;
}
myDisplayer("Calculating...");
let result = calculate();
myDisplayer(result);
Try it Yourself »
Can Asynchronous Programming Help?
Timers, Promises, and async/await do not solve this problem.
They all execute JavaScript on the same main thread.
If the thread is busy performing calculations, the browser must still wait.
Example
myDisplayer("Start");
setTimeout(function () {
myDisplayer("Timer")}, 1000);
let i = 5e9;
while (--i > 0);
myDisplayer("Finished");
The timer finishes after one second, but its callback cannot run until the loop has completed.
Try it Yourself »What Is a Web Worker?
A Web Worker runs JavaScript in a separate thread.
While the worker performs calculations, the browser's main thread remains free to respond to user input.
The main thread and the worker communicate by sending messages.
Browser Support
Before creating a worker, check whether the browser supports Web Workers.
Example
if (typeof(Worker) !== "undefined") {
myDisplayer("Web Workers are supported.");
} else {
myDisplayer("Web Workers are not supported.");
}
Try it Yourself »
Creating a Worker
Create a worker with the new Worker() constructor.
const worker = new Worker("worker.js");
The file passed to the constructor contains the code that will run in the worker thread.
Receiving Messages
The main thread receives messages with the onmessage event.
Example
const worker = new Worker("worker.js");
worker.onmessage = function(event) {
myDisplayer(event.data);
};
Try it Yourself »
Sending Messages
The main thread sends data to the worker with postMessage().
Main page:
const worker = new Worker("worker.js");
worker.postMessage(25);
worker.js
onmessage = function(event) {
postMessage(event.data * event.data);
}
Result
625
Complete Example
Example
const worker = new Worker("worker.js");
worker.onmessage = function(event) {
myDisplayer(event.data);
};
worker.postMessage(1000000);
worker.js
onmessage = function(event) {
let sum = 0;
for (let i = 0; i <= event.data; i++) {
sum += i;
}
postMessage(sum);
};
Note
The calculation happens in the worker.
The page remains responsive.
Summary
- Web Workers run JavaScript in a separate thread.
- Workers keep the main thread responsive during long-running calculations.
- Create a worker with
new Worker(). - Workers communicate using
postMessage(). - Receive messages with the
onmessageevent.