Web Workers: A Practical Guide to Multithreading in JavaScript
Web Workers are a simple means for web content to run scripts in background threads. The worker thread can perform tasks without interfering with the user interface. In addition, they can make network requests using the fetch()
or XMLHttpRequest
APIs. Once created, a worker can send messages to the JavaScript code that created it by posting messages to an event handler specified by that code (and vice versa).
As we know that JavaScript is single threaded due to the fact that it was created for web browsers. Multiple operations on DOM at once can have side effects.
Let’s get started on how to create a web worker.
A Worker is an object created using an constructor that runs a named JavaScript file. You can run anything inside worker but there are few exceptions. You cannot directly access DOM elements inside a worker. Also you cannot access some of the default method and properties of window object.
Data is sent between workers and main thread via a system of messages — both sides send their messages using the postMessage()
method, and respond to messages via the onmessage
event handler (the message is contained within the message
event's data attribute). The data is copied rather than shared.
In this blog, we will only focus on Dedicated Workers.
For this, we will setup a simple project. We will multiply two numbers inside worker and will return the result to main thread.
First, we will check if Web Workers are supported by current browser. To do this, here is the following code to check:
if (window.Worker) {
const myWorker = new Worker("worker.js");
} else {
console.log("Your browser doesn\'t support Web Workers");
}
If browser supports Web Worker, then we will create new object myWorker
. Here worker.js
is the JS file that contains Web Worker code.
Create a new file called worker.js
.
Following code multiplies two numbers and return result to main thread.
onmessage = function (e) {
console.log('Worker: Message received from main script');
const result = e.data[0] * e.data[1];
if (isNaN(result)) {
postMessage('Please write two numbers');
} else {
const workerResult = 'Result: ' + result;
console.log('Worker: Posting message back to main script');
postMessage(workerResult);
}
}
Following is the code inside main.js
file.
const first = document.querySelector('#number1');
const second = document.querySelector('#number2');
const result = document.querySelector('.result');
if (window.Worker) {
const myWorker = new Worker("worker.js");
[first, second].forEach(input => {
input.onchange = function () {
myWorker.postMessage([first.value, second.value]);
console.log('Message posted to worker');
}
})
myWorker.onmessage = function (e) {
result.textContent = e.data;
console.log('Message received from worker');
}
} else {
console.log('Your browser doesn\'t support web workers.');
}
In the above code, myWorker.postMessage()
send number array to worker.
myWorker.onmessage()
is the event listener that listens to the Worker.
Checkout this repository for complete implementation: https://github.com/avirajkhare00/web-workers
In the next tutorial, we will dive deep into the Web Workers and take a look under the hood.
Keep coding…