Javascript

Web Workers Tutorial: Learn how Javascript Web Workers Work

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.

Webworker flow

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

javascript Copy
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

javascript Copy
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

javascript Copy
// 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

javascript Copy
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.

javascript Copy
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.

Last Updated Saturday, 12 June 2021
Click to Subscribe Subscribed

Subscribe

Subscribe to stay up to date with our latest posts via email. You can opt out at any time.

Not a valid email