Web Workers Tutorial: Learn how Javascript Web Workers Work
📣 Sponsor
Javascript is a single threaded language. All it means is Javascript runs on one process. It can only do one thing at a time in your code.
This is usually fine, since Javascript is really fast. Sometimes though, it isn't fast enough. When we want more than one process at once running, we have to use web workers.
When are Web Workers Useful?
On complex, large applications, Javascript can only run the file or function you are trying to use from top to bottom. If we are doing a lot of high computation processes on top of each other, it can become problematic.
Imagine a simple image upload website, that identifies objects in a photo. You upload the image, and then the image is processed by a complex algorithm to identify objects in the frame. Since Javascript is one threaded, the website will pause until that processing is complete.
If we ran the processing on a second thread, the user could still interact and use the website, while waiting for the processing to complete.
As you can see above, web workers let us run two pieces of code in parallel.
How do web workers .. work?
Web workers aren't as complicated as you'd expect. Below is a sample of a simple web worker built in vanilla frontend Javascript. Let's look at how it works.
main.js
let myWebWorker = new Worker('./thread.js');
document.getElementById('button').addEventListener('click', function(e) {
myWebWorker.postMessage({ "message" : "outcome" });
});
myWebWorker.onmessage = (e) => {
console.log(`Message received from web worker.. Message is ${e.data}`);
}
myWebWorker.onerror = (error) => {
console.log(`We ran into an error with your web worker.. Error is ${error}`);
}
thread.js
onmessage = (e) => {
postMessage(e.data);
}
In main.js, when the user clicks on the button, a message will be posted to our web worker, which is found in thread.js. This message can be in various formats, including Blob, File, Object, Array, Text, or Number.
In thread.js, we have an onmessage event handler, which will handle the data coming from our main.js file. We can access the data with data
, which will contain the object we sent with postMessage ({ "message" : "outcome" }
).
Finally, when the thread.js file uses postMessage, we can pick it up again in main.js using myWebWorker.onmessage
. We can then display the results of the web worker processing back to the user. In this case, we have just console logged the original message.
How do web workers work in Node.JS
There are some minor differences in Node.JS, which we'll cover here. Essentially, we have to import the web workers to make it work properly:
main.js
// Web Workers
import { Worker, isMainThread, parentPort, workerData } from 'worker_threads';
const worker = new Worker('./thread.js');
// Post a message
worker.postMessage("Hello");
// Wait for an output
worker.on('message', function(result) {
console.log(result);
});
// Capture any errors
worker.on('error', function(result) {
console.log(error);
});
thread.js
import { workerData, parentPort } from 'worker_threads';
parentPort.on('message', function(data) {
parentPort.postMessage("Goodbye");
});
A major difference between Node.JS and vanilla Javascript is the fact that we use the on()
function, rather than onmessage
. As well, the data we receive back is available in the directly, without having to use e.data
, so we can just call e
to get our data back.
The global object in Web Workers
Normally on the web, when we want to refer to the global object, we refer to window
, self
, or more recently globalThis
. In webworkers, the way we reference the equivalent of the window
object, is by using self
.
self.someVariable = 'name'
What are the limitations of web workers?
Web workers have a few limitations which make them different from typical Javascript:
- You can't manipulate DOM elements.
- You can't create new elements.
- You can't load images.
Although web workers have all these limitations, we can still outsource intensive tasks to web workers, and when they send a response, we can add new items to the DOM in the main thread Javascript.
More Tips and Tricks for Javascript
- Javascript Math Tutorial: How to do Math in Javascript
- Javascript Array Filter Method
- How does the Javascript logical OR (||) operator work?
- Javascript Temporal and How it Works
- Making your own Express Middleware
- Truthy and Falsy Values in Javascript
- Javascript Shallow Copies - what is a Shallow Copy?
- How to get the last element of an Array in Javascript
- Inserting an Item into an Array at a Specific Index in Javascript
- How fetch works in Javascript