How to implement Web Workers?

If you are a web developer, you must have faced or will face a situation where you have to load considerably large data from an API or another source into your web app. Handling large data in the backend ( server-side ) is not the same as in a browser. We will have control over the hardware and architecture in the case of a backend system but we are talking about the client’s browser in the case of a website ( the HTML and js part ), for all we know people might be using the Internet Explorer as their primary browser ( yes they still exist ). Enter Web workers.

Web workers is a way to implement multi-threading in javascript, specifically in the browser. In this article, we will explore the concept of Web workers and build a simple web application implementing it.

What are web workers?

Web workers is an API used to run javascript code in a background thread on a browser. It is not baked into javascript rather it’s a feature provided by the browsers and a part of HTML5 standard, So javascript is still single-threaded and asynchronous. Below is the list of supported browsers.

web workers - browser support
Browser support

Web workers are of three types,

  • Shared web worker
  • Dedicated web worker
  • Service worker ( See my article on PWAs, which will show how service workers are used in a web application ).

For this article, we will be looking at Dedicated web workers and we will call them simply Web workers, the rest are beyond the scope of this article.

How does it work?

In this section, we will see how web workers handle js in the background.

  • We can initiate a worker inside a script with the command new Worker(<filename.js>).

Note: We cannot spin off a worker inline like other programming languges ( example: java, C#, php ), rather we can only load js files. There are ways to implement it inline but, its beyond the scope of this article ( Refer this link ).

  • The above command will initiate a web worker in another thread. Every variable, object, and function declared inside the worker will be in its own scope, meaning we cannot access a variable declared inside a web worker from a js file directly.
  • We can only communicate with a worker using Broadcast Channel.
  • To put it simply we will send a value ( string/object/number ) from a js file to a web worker or vice versa using this.postMessage(<data>).
  • We can receive data from a js or web worker file with this.onmessage = (data)=> ( incase of web worker ) and worker.onmessage = (data)=> ( in case of a js file, worker object is obtained from new Worker() instance ).
  • We can terminate a worker using either worker.terminate() ( In case of the main thread JS file ) or this.close() ( In the case of a Web worker ).

Sample application:

In this section, we will create a simple web application and implement web workers in it.

web workers - folder structure
Folder structure

The above picture shows our application’s folder structure, we will send data from HTML to the web worker and print it.

index.html:

web workers - index file
Index.html

We have a simple HTML page, with no components just displaying the text “Sample web workers”.

  • In the first line of the script, we initiate a worker by a new Worker(‘src/worker.js’).
  • Following line, we send data to that web worker with worker.postMessage(‘Hi this is Js’). We can also send objects and raw binary data using ArrayBuffer.
  • We cannot send functions as web worker API uses a structured clone algorithm for copying objects and it doesn’t support copying functions.

That’s it, on the next section we will explore our worker.js file.

worker.js:

web workers - worker file
worker.js

In this file, we just simply listen to the data. this.onmessage will listen for the data from the file that initiated it ( In our case it’s the HTML file ).

If you want to send data from the worker to the js file see the below code.

web workers - worker file updated
worker.js ( updated )

here we just send the data using the same postMessage function that we used in our js file and this.close()will terminate the web worker.

Note: It is best practice to terminate a web worker when not needed. Not doing so may lead to memory leaks

web workers - index updated
Index.html ( updated )

Here we listen for the message from the worker file and console it. Note that we use worker.onmessage not this.onmessage because we are listening to the data from the worker.

We cannot open the HTML page in a browser directly, as Web workers need an origin to work. So you can either use VS code extension Live Server or serve npm package for serving the files, both are simple and easy to use.

Result:

When you run the file in the browser, you will see two console logs one from the worker, and another from our HTML file.

web workers - result 1
Result 1

When you expand any one of the consoles you find a lot of information in the object, the “data” key contains the value that we sent.

web workers - result 2
Result 2

Limitations:

As with any other feature, we have some limitations with web workers also, some of them are listed below.

  • Creating web workers will span real OS-Level threads that consume system resources. So we have to plan ahead on which situations to use them.
  • Web workers don’t have access to DOM, window, or document object. So if we want to display or manipulate the DOM objects based on the data from a worker, we have to get data from that particular web worker through channels.
  • Web workers use a structured clone algorithm for copying objects and they are not given time to clean allocated memory. So terminating web workers abruptly may lead to memory leaks.

Use Cases:

So when do we need web workers, below are some scenarios where we can make use of it.

  • Prefetching data from API.
  • Complex updation on Browser DB ( example Index DB ).
  • Image filtering and rendering.
  • Processing media data ( Video and Audio ).

Conclusion:

As features grow in our web application, we cannot handle everything on the main thread. Yes, javascript is asynchronous, but event loops will get filled eventually and we need a way to handle things efficiently on the browser, web workers are a great way to do this given used sensibly.

Happy coding !!!

Github repo link: https://github.com/kishork2120/Webworkers-tutorial

4 thoughts on “How to implement Web Workers?

Leave a Reply

Your email address will not be published.

Pin It on Pinterest