When you're dealing with JavaScript tasks that take a lot of time and involve complex calculations, it can freeze up the web page, making it unresponsive. This happens because JavaScript always runs in the foreground.
HTML5 introduces a feature known as web workers, which is specifically crafted to manage background tasks autonomously, separate from other scripts. This way, the page remains responsive even when heavy tasks are running in the background, without affecting its performance.
Tip: Major modern browsers like Firefox, Chrome, Opera, Safari, and Internet Explorer 10 and above support HTML5's web worker feature.
Web workers are often used for tasks that consume a lot of time. For example, let's say we want to count from zero to 100,000. We can create an external JavaScript file named "worker.js" with the following code:
var i = 0;
function countNumbers() {
if(i < 100000) {
i = i + 1;
postMessage(i);
}
// Wait for sometime before running this script again
setTimeout("countNumbers()", 500);
}
countNumbers();
Note: Web workers cannot access the DOM. This means you cannot manipulate any DOM elements in the JavaScript code executed by web workers.
Tip: The postMessage()
method of the worker object sends a message (in this case, numbers) back to the web page from the web worker file.
Now that we have our web worker file, let's initiate it from an HTML document. This will execute the code inside "worker.js" in the background and display the result progressively on the web page:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Using Web Worker</title>
<script>
if(window.Worker) {
// Create a new web worker
var worker = new Worker("worker.js");
// Fire onMessage event handler
worker.onmessage = function(event) {
document.getElementById("result").innerHTML = event.data;
};
} else {
alert("Sorry, your browser do not support web worker.");
}
</script>
</head>
<body>
<div id="result">
<!--Received messages will be inserted here-->
</div>
</body>
</html>
The JavaScript code in the example does the following:
Note: The code executed by a worker is always stored in a separate JavaScript file to prevent it from accessing global variables or manipulating elements on the web page.
Now, let's learn how to start and stop a worker from a web page by clicking HTML buttons. We'll use the same "worker.js" file to count from zero to 100,000. Here's how:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Start/Stop Web Worker</title>
<script>
// Set up global variable
var worker;
function startWorker() {
// Initialize web worker
worker = new Worker("worker.js");
// Run update function, when we get a message from worker
worker.onmessage = update;
// Tell worker to get started
worker.postMessage("start");
}
function update(event) {
// Update the page with current message from worker
document.getElementById("result").innerHTML = event.data;
}
function stopWorker() {
// Stop the worker
worker.terminate();
}
</script>
</head>
<body>
<h1>Web Worker Demo</h1>
<button onclick="startWorker();" type="button">Start web worker</button>
<button type="button" onclick="stopWorker();">Stop web worker</button>
<div id="result">
<!--Received messages will be inserted here-->
</div>
</body>
</html>
Tip: Web workers are best suited for handling heavy-weight JavaScript tasks that do not interfere with user-interface scripts, such as those responding to clicks or other user interactions. Avoid using web workers for short tasks.