HTML5 Web Workers
JavaScript is single-threaded, meaning it can only do one thing at a time. If a script needs to perform a very time-consuming, compute-intensive task (e.g., processing large amounts of data, complex mathematical calculations), it will block the main thread, causing the entire user interface (UI) to freeze. The page cannot respond to any user actions (like clicking, scrolling), resulting in a very poor user experience.
Web Workers were introduced in HTML5 to solve this problem. A Web Worker is a JavaScript script that runs in the background, independent of the main thread, without affecting page performance and responsiveness.
Characteristics of Web Workers
- Background thread: Workers run in a background thread separate from the main thread.
- No UI blocking: You can delegate time-consuming computation tasks to Workers while the main thread remains free to handle user interactions and DOM updates.
- Restricted access: For thread safety, Workers cannot directly access the main thread's
windowobject,documentobject, or DOM nodes from the parent page. - Communication mechanism: Workers communicate with the main thread through a message passing mechanism.
How to Use Web Workers
Using Web Workers involves three main steps: creating the Worker, sending and receiving messages between the main thread and Worker, and terminating the Worker.
1. Create the Worker File
First, you need to create a separate .js file, which we'll call demo_worker.js. This file will contain the code you want to execute in the background.
demo_worker.js:
// A simple counting task
let i = 0;
function timedCount() {
i = i + 1;
// Send the current count back to the main thread
postMessage(i);
setTimeout(timedCount, 500);
}
timedCount();postMessage() is the method for Workers to send messages to the main thread.
2. Create and Control the Worker in the Main Page
In your main HTML page, you can create and interact with the Worker.
<p>Count: <output id="result"></output></p>
<button onclick="startWorker()">Start Worker</button>
<button onclick="stopWorker()">Stop Worker</button>
<script>
let w;
function startWorker() {
// Check if browser supports Web Worker
if (typeof(Worker) !== "undefined") {
// If w hasn't been created, create a new Worker
if (typeof(w) == "undefined") {
w = new Worker("demo_worker.js");
}
// Listen for messages from the Worker
w.onmessage = function(event) {
document.getElementById("result").innerHTML = event.data;
};
} else {
document.getElementById("result").innerHTML = "Sorry, your browser does not support Web Workers...";
}
}
function stopWorker() {
// Terminate the Worker
if (typeof(w) !== "undefined") {
w.terminate();
w = undefined; // Reset the Worker variable
}
}
</script>new Worker("demo_worker.js"): Creates a new Web Worker object.w.onmessage: Sets up an event listener to receive data sent back by the Worker viapostMessage(). The data is contained in theevent.dataproperty.w.terminate(): Immediately terminates the Worker's execution. This is a way to stop the Worker from the main thread side.
This example clearly shows how to put a continuously running counting task in the background while the main page can freely respond to user "start" and "stop" actions, and the UI won't freeze.