What are web workers?

What are web workers?

A web worker is a JavaScript code that runs in the background and does not influence the page’s performance.

As we know, JavaScript is a single-threaded language, meaning that it can only process one task at a time.

Example 1

let t = new Date();
console.log(`tastk 1 took: ${new Date() - t}ms`);
console.log(`tastk 2 took: ${new Date() - t}ms`);
console.log(`tastk 3 took: ${new Date() - t}ms`);

In the example given above, we will see the following output in the console, in the same sequence:

tastk 1 took: 0ms
tastk 2 took: 1ms
tastk 3 took: 2ms

Because these tasks are simple, when we open the console, we’ll see that all three lines have been printed with almost no time in between them.

But what if one of these tasks took a longer time than the others?

Example 2

let t = new Date();
console.log(`tastk 1 took: ${new Date() - t}ms`);
console.log(`tastk 2 took: ${new Date() - t}ms`);
let i = 0;
while (i <= 1000000000) {
i++;
}
console.log(`tastk 3 took: ${new Date() - t}ms`);

It will take much longer to run task 3.

Example 3

Note: The browser may issue a warning, for instance, “this page is slowing down your browser.” In that case, the page will be frozen until the calculation is complete.

  • HTML
Synchronous task

The first button is a simple counter, which begins counting as soon as we click it.

The other button is a piece of code that takes a long time to run.

When we click it, we’ll see that the counter and the rest of the page are frozen until the calculation is completed.

Using web workers

This is where web workers come in to help.

If a process is likely to take a long time, the user is not expected to wait until it is complete. A long waiting time results in a poor user experience.

Therefore, such long tasks should be performed in the background.

We will create another button called Worker Calculation.

Now, we will move the logic of the long calculation to a separate file named worker.js.

Instead of alerting the value directly, we will use the postMessage method.

Then, we will create a workerCalculation function and do the following:

  • Create a worker instance.
  • Include the worker’s path.
  • Add an onmessage callback that takes an event as an argument.

We’ll use this callback to alert the data that comes from the postMessage method when the calculation is complete.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Web Workers</title>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<!-- counter -->
<script>
let i = 0;
let intervalId = null;
const counter = () => {
if (!intervalId) {
intervalId = setInterval(() => {
i++;
document.getElementById("counter").innerText = i;
}, 300);
} else {
clearInterval(intervalId);
i = 0;
document.getElementById("counter").innerText = i;
intervalId = null;
}
};
</script>
<!-- longCalculation -->
<script>
const longCalculation = () => {
let i = 0;
while (i <= 10000000000) {
i++;
}
alert("Long calculation finished!");
};
</script>
<!-- workerCalculation -->
<script>
const workerCalculation = () => {
let worker = new Worker("worker.js");
worker.onmessage = (e) => {
alert(e.data);
};
};
</script>
</head>
<body>
<h3>Counter: <span id="counter"> # </span></h3>
<button onclick="counter()">Start Counter</button>
<button onclick="longCalculation()">Long Calculation</button>
<button onclick="workerCalculation()">Worker Calculation</button>
</body>
</html>
Web workers

Output

Browser support

Not all browsers support web workers.

We need to check whether or not the user’s browser supports web workers, before creating one:

if (typeof Worker !== "undefined") {
  // Yes!
} else {
  // No!
}

Hence, our worker.js file should be:

if (typeof Worker !== "undefined") {
  let i = 0;
  while (i <= 1000000000) {
    i++;
  }
  postMessage("Worker calculation finished!");
} else {
  alert("Your browser doesn't support web workers.");
}

Note: Download the final GitHub Repo.

Free Resources