How to Use HTML5 Web Workers

Find out how to execute JavaScript code in the back with the HTML5 web workers in this article.


What is Web Worker?

When attempting to execute resource-intensive operations in JavaScript that involve substantial calculations and consume a significant amount of time, the web browser will become unresponsive, preventing users from performing any actions until the task is completed. This occurs because JavaScript code always runs in the foreground.

To address this issue, HTML5 introduces a novel technology known as web workers. Web workers are specifically designed to perform background work independently of other user interface scripts, ensuring that the page's performance remains unaffected. Unlike regular JavaScript operations, web workers operate in the background, allowing the web page to remain responsive without interrupting the user.

Note: It's important to note that HTML5's web worker feature is supported by all major modern web browsers, including Firefox, Chrome, Opera, Safari, and Internet Explorer 10 and above.

JavaScript web workers offer the advantage of running background tasks in HTML, allowing for parallel processing and improved performance. They enable developers to handle intensive tasks efficiently, whether synchronously or asynchronously. Additionally, web workers facilitate real-time data processing, enhancing the responsiveness and user experience of HTML-based applications.


Create a Web Worker File

One of the simplest applications of web workers is to handle time-consuming tasks. In this case, we will create a basic JavaScript task that counts from zero to 100,000.

To accomplish this, let's create an external JavaScript file named worker.js and input 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: Please keep in mind that web workers do not have the ability to access the Document Object Model (DOM). This implies that you cannot interact with any DOM elements within the JavaScript code that you intend to execute using web workers.

Tip: In order to send a message, such as the numbers in the aforementioned example, from the web worker file back to the web page, you can utilize the postMessage() method of the worker object.


Doing Work in the Background with Web Worker

Now that we have successfully generated our web worker file, we will proceed to initiate the web worker from an HTML document. This initiation involves executing the code contained within the "worker.js" file in the background while gradually displaying the resulting output on the web page. Let's observe how this process functions:

<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(" your browser do not support web worker.");
}
</script>

<body>
<div id="result">
<!--Received messages will be inserted here-->
</div>
</body>

  • The declaration var worker = new Worker("worker.js"); instantiates a fresh web worker object, facilitating communication with the associated web worker.
  • Upon the web worker posting a message, it triggers the execution of the onmessage event handler, enabling the code to collect messages from the web worker.
  • The content of the message dispatched by the web worker resides within the event.data element.

Note: It's important to note that the code executed by a web worker is always stored in a separate JavaScript file. This separation is in place to prevent web developers from writing web worker code that attempts to utilize global variables or directly access elements on the web page.

Utilizing web workers for background tasks allows for efficient execution, as JavaScript web workers enable the running of tasks in the background, supporting parallel processing and multithreading to enhance performance and facilitate seamless background task execution.


Terminate a Web Worker

Up to this point, you have learned how to create a worker and receive messages. However, it is also possible to terminate a running worker in the middle of its execution.

To terminate a web worker, you can call the terminate() method on the web worker object. This method immediately stops the worker's execution and releases its resources.

The upcoming example demonstrates how to start and stop a worker from a web page by utilizing HTML buttons. It uses the same JavaScript file, worker.js, that we previously used. Let's give it a try:

<script>
// Set up global variable
var worker;

function startWorker() {
    // Initialize web worker
    worker = new Worker("worker.js");

    // Update result, when we get a message from worker
    worker.onmessage = function (event) {
        document.getElementById("result").innerHTML = event.data;
    };
}

function stopWorker() {
    // Stop the worker
    worker.terminate();
}
</script>

<body>
<h1>Web Worker Demo page</h1>
<button onclick="startWorker();" type="button">Begin web worker</button>
<button type="button" onclick="stopWorker();">End web worker</button>
<hr />
<div id="result">
<!--Received messages will be inserted here-->
</div>
</body>

Note: Web workers should be used solely for executing resource-intensive JavaScript tasks that do not disrupt user-interface scripts, such as those triggered by clicks or other user interactions. It is not recommended to employ web workers for small tasks.

When it comes to terminating a web worker, developers can effectively stop its execution by following proper procedures such as ending a JavaScript web worker, stopping the execution of a web worker, or terminating the web worker thread. This ensures the prompt discontinuation of background tasks and the proper termination of a running web worker process or script.


FAQ

What are HTML5 Web Workers?

HTML5 Web Workers are a browser feature that allows you to run JavaScript code in the background, separate from the main execution thread of a web page. Web Workers enable multi-threading in web applications, which can improve performance by offloading intensive tasks from the main thread, preventing UI blocking and improving responsiveness.

Why are Web Workers useful?

Web Workers are useful for performing tasks that are computationally intensive, time-consuming, or require continuous processing without affecting the main thread's responsiveness. By moving such tasks to a separate thread, Web Workers allow the main thread to focus on user interactions and rendering, resulting in a smoother user experience.

How do you create a new Web Worker?

To create a new Web Worker, you need to create a separate JavaScript file containing the code you want to run in the background. Then, you can create a new instance of the Worker object and provide the URL of the worker script. Here's an example:

// main.js
const worker = new Worker('worker.js');

How can the main thread communicate with a Web Worker?

Communication between the main thread and a Web Worker is achieved through a messaging system. You can use the postMessage() method in the main thread to send data to the worker, and the worker can respond by listening for the message event and using the postMessage() method as well.

How do you handle messages sent from a Web Worker in the main thread?

In the main thread, you can listen for the message event on the worker instance. When a message is received from the worker, you can access the message data using the event.data property. Here's an example:

worker.onmessage = function(event) {
  const messageData = event.data;
  console.log('Message received from worker:', messageData);
};

What kind of data can be transferred between the main thread and a Web Worker?

You can transfer structured data such as strings, numbers, arrays, objects, and certain typed arrays using the messaging system. Data is serialized and deserialized automatically. However, not all data types can be transferred, and complex objects with functions or circular references cannot be cloned and transferred.

How do Web Workers help with UI responsiveness?

Web Workers run in the background, separate from the main thread responsible for UI rendering and user interactions. This separation prevents long-running or CPU-intensive tasks from blocking the main thread, ensuring that the UI remains responsive and doesn't freeze while performing these tasks.

Are there any limitations to using Web Workers?

Yes, there are some limitations to using Web Workers:

  • Web Workers cannot access the DOM directly.
  • Web Workers have limited access to global variables and functions.
  • Cross-origin restrictions apply when loading worker scripts from different domains.
  • Some browser-specific limitations and differences might exist.

Do Web Workers share memory with the main thread?

No, Web Workers do not share memory with the main thread. They operate in separate threads with their own isolated memory space. Communication between the main thread and workers is achieved through message passing.

Can you provide an example of using a Web Worker for a time-consuming task?

Certainly! Here's a simplified example of using a Web Worker to calculate the factorial of a large number:

main.js:

const worker = new Worker('worker.js');

worker.onmessage = function(event) {
  const result = event.data;
  console.log('Factorial result:', result);
};

const number = 10;
worker.postMessage(number);

worker.js:

function calculateFactorial(number) {
  if (number <= 1) return 1;
  return number * calculateFactorial(number - 1);
}

self.onmessage = function(event) {
  const inputNumber = event.data;
  const factorialResult = calculateFactorial(inputNumber);
  self.postMessage(factorialResult);
};

In this example, the main thread sends a number to the Web Worker to calculate its factorial. The Web Worker performs the calculation in the background and sends the result back to the main thread.

What types of Web Workers are available in HTML5?

There are two types of Web Workers in HTML5: Dedicated Web Workers and Shared Web Workers.

  • Dedicated Web Workers: These are the most common type of Web Workers. Each dedicated Web Worker runs in its own thread and is dedicated to a single parent script that created it.
  • Shared Web Workers: Shared Web Workers allow multiple scripts running in different windows, tabs, or frames to communicate and share data through a single worker instance. This type of worker can be useful for scenarios where multiple browsing contexts need to collaborate on a task.

Do Web Workers support ES6 modules?

Yes, modern browsers generally support using ES6 modules within Web Workers. You can use the import and export syntax to organize and share code between the main thread and worker scripts. However, browser compatibility might vary, so it's a good idea to check compatibility tables before using ES6 modules.

How can you terminate a Web Worker?

You can terminate a Web Worker by calling the terminate() method on the worker instance from the main thread. This will immediately stop the worker's execution and free up its resources. For example:

worker.terminate();

Are Web Workers supported in all browsers?

Web Workers are supported in most modern browsers, including Chrome, Firefox, Safari, Edge, and Opera. However, some older browsers might have limited or no support for Web Workers, so you should check compatibility if you need to support older versions.

Can you create multiple Web Worker instances for different tasks?

Yes, you can create multiple Web Worker instances for different tasks. Each Web Worker instance operates independently in its own thread. This allows you to parallelize different tasks and improve performance, especially on multi-core processors.

Are Web Workers suitable for all types of tasks?

While Web Workers are great for CPU-intensive tasks, they might not be suitable for tasks that involve frequent UI updates or tasks that rely heavily on synchronous operations. Additionally, tasks that require direct access to the DOM should be performed on the main thread.

How does error handling work in Web Workers?

Errors that occur in a Web Worker do not propagate to the main thread by default. To handle errors, you can use the onerror event handler within the worker script. When an error occurs, you can send an error message to the main thread using the postMessage() method. The main thread can listen for errors using the worker's onerror event handler.


Conclusion

HTML5 Web Workers are separate JavaScript code that runs in the background of a web page without affecting the user Interface. The Web Workers API makes it possible to execute a JavaScript file asynchronously and autonomously,allowing you to prevent the execution of bigger tasks from freezing up your web page.

The Web Workers API is an excellent alternative to multithreaded architecture, making it increasingly difficult to write smooth and responsive apps. It allows multithreaded JavaScript web apps to exploit parallel processors, and the HTML5 specification for copying complex JavaScript objects introduces a shared-nothing concurrency model as the first step towards concurrent web applications.