JavaScript is traditionally a single-threaded language. This means it can only do one thing at a time. If you write a script that performs a massive mathematical calculation or processes thousands of rows of data, the entire web page will completely "freeze" until that calculation is finished. Users won't be able to click buttons, scroll, or type.
HTML5 introduced the Web Worker API to solve this exact problem. A web worker is a JavaScript file that runs entirely in the background, independently of the main browser window (the UI thread).
Because Web Workers spin up a separate "thread" in the background, they can crunch numbers and process heavy tasks while the user continues to use your website smoothly without any stuttering.
However, because they run outside the main page, Web Workers are placed under strict limitations:
document.getElementById() inside a worker).window object.parent object.Instead, the main webpage and the Web Worker communicate by sending messages back and forth to each other.
To use a Web Worker, you must create a separate JavaScript file that contains the code you want to run in the background. Let's call it worker.js.
Inside the worker file, you use the postMessage() method to send data back to the main webpage.
// Inside worker.js
let count = 0;
function timerCount() {
count = count + 1;
// Send the updated count back to the HTML page
postMessage(count);
// Repeat this every 1 second
setTimeout("timerCount()", 1000);
}
timerCount();
On your actual webpage, you instantiate the worker, listen for messages coming from it, and handle stopping it when it is no longer needed.
<p>Count: <span id="result">0</span></p>
<button onclick="startWorker()">Start Worker</button>
<button onclick="stopWorker()">Stop Worker</button>
<script>
let myWorker;
function startWorker() {
// Check if the browser supports Web Workers
if (typeof(Worker) !== "undefined") {
// Prevent creating multiple workers if one is already running
if (typeof(myWorker) == "undefined") {
myWorker = new Worker("worker.js");
}
// Listen for the postMessage() data sent FROM the worker
myWorker.onmessage = function(event) {
document.getElementById("result").innerHTML = event.data;
};
} else {
document.getElementById("result").innerHTML = "Sorry! No Web Worker support.";
}
}
function stopWorker() {
// Instantly terminate the background thread
myWorker.terminate();
// Clear the variable
myWorker = undefined;
}
</script>