Web Workers with the Angular CLI

A guide for a simple way to build Web Workers with the Angular CLI and performance comparison with and without a Web Worker

Photo by Hoang Tran on Unsplash

Although web workers have been around for a while, frontend engineers seem to avoid using them in projects. There is some documentation on the Angular website, but this article will show how to generate workers, test their performance, and show real use-cases for them. With this knowledge, I hope you will be ready to begin integrating them in your existing code.

For more content like this, check out https://betterfullstack.com

What we will do in this article:

Basic web worker knowledge How to create web workers with the angular-cli from scratch Understand the performance of web workers Provide cases that could utilize web workers

Basic web worker knowledge

Web Workers allow you to run CPU intensive computations in a background thread, freeing the main thread to update the user interface.

As you know, when we execute the script on the HTML page, the page will become unresponsive until the script has finished. During that time, the user cannot do anything — we have all experienced the pain of needing to wait multiple seconds for a complicated task to finish before an app becomes usable.

Web workers will put these complex calculations which take more than 3 seconds or 5 seconds in the background thread and allow the user to continue their job.

Here are some points we need to pay attention when using web workers:

Create a worker by new Worker(scriptURL, options) . Using postMessage as a way to send data to the worker or a way to return data from the worker and handled where onmessage is called. Using onmessage to get the result from worker. Using terminate when you want to stop web workers and free browser resources.

How to create a web worker with the angular-cli

You can add a web worker anywhere in your application. If the file that contains your expensive computation is src/app/app.component.ts , you can add a Web Worker using this command.

Running this command will:

a. Configure your project to use Web Workers, if it isn’t already.

CREATE tsconfig.worker.json

UPDATE tsconfig.app.json

UPDATE angular.json

b. CREATE src/app/app.worker.ts

c. UPDATE src/app/app.component.ts

The Angular CLI will automatically put this logic at the bottom of the app.component.ts file. So you need to move it into a component and refactor it again.

We also have another CLI syntax to create web workers:

ng generate webWorker <name>[options]

You can read more here.

Common errors you may see in the console

“Expected 2–3 arguments, but got 1” for postMessage : As I understand it currently, it seems there are two versions of web workers.

Expected 2–3 arguments, but got 1

One from Visual Studio we need to provide three 3 parameters with two of them required. However, If you look at this documentation, we just have two parameters and only one is required.

Solution: add declare function postMessage(message:any): void; on the top of the worker file.

“Expected 1 arguments, but got 2” for new Worker

Expected 1 arguments, but got 2

The same for this issue. But according to this document, we have two arguments actually.

Solution: Just ignore it. The code will run without any error.

In the documentation, they don’t mention what the type module is. From my understanding, I think a web worker is only put in the bundle of the file when we put type: 'module' . If the browser cannot see the worker, it will get the error below.

GET http://localhost:4200/app.worker 404 (Not Found)

Note: if you do not see the warning and still get a not found issue for new Worker , it means that you have to re-run the server again.

Last error is function() could not be cloned . This is because the message to send to the service worker can be any structured-clonable type. It is a long story, but you can read this to learn more.

function() could not be cloned

Solution: Do not put the function inside the message to solve this issue.

If you find any issues, you can comment below. I will update the article. Thanks!

Performance with web workers

> Find the source code for this example here.

Performance is always crucial. Let’s see what kind of gains we can expect using web workers.

I will compare between single-threaded JavaScript and using a web worker for doing a complicated calculation to find prime numbers out of 10,000,000.

First, look at the UI when clicking on thread button

User click on JavaScript Thread button

This will make your browser hang out for a while. In this situation, it takes 210 seconds. I mean nearly 4 minutes that you can’t do anything and sit in front of the computer like a fool. Notice that the button stays pressed in while the calculations run.

After the calculation has finished and the main thread was released, that allows the user to engage the interface. You can see the result below. It took so long for this calculation.

Result 210 seconds to calculate

Now, Look at the UI after clicking on the Web Worker button

User click on Web Worker button

You can see immediately the UI become responsive right after the click, and the result to run this calculation is 1 second only. The calculation will be run in the background, and the response is sent to the interface after finding the result.

Result after completing the calculation

What does this mean? The scripting time when using a Web Worker is far less than the normal way that we usually do things.

Use cases for web workers

After we understand the benefit of web workers and how to implement them, the next thing to do is find real-life cases where they can apply. Here are a few instances that I think web workers would be beneficial:

Progressive Web Apps Calculation on large list or array Fetching or caching data Syntax highlighting or real-time text formatting Spell checking Update extensive data on a local web database Compress or decompress a file Image filtering

You can comment below for other cases that use Web Workers.

Summary

Using Web Workers is not hard. This could be a key solution for performing complicated tasks that consume excessive browser resources.

I hope you found this article useful! You can follow me on Medium. I am also on Twitter. Feel free to leave any questions in the comments below. I’ll be glad to help out!

You can check source code here.

Resources / References

[1]: Web Workers on W3 Schools https://www.w3schools.com/html/html5_webworkers.asp

[2]: Using Web Workers https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers

[3]: Using Web Workers with Angular CLI https://angular.io/guide/web-worker

[4]: Computing with JavaScript Web Workers https://johnresig.com/blog/web-workers/

[5]: How JavaScript works: The building blocks of Web Workers + 5 cases when you should use them https://blog.sessionstack.com/how-javascript-works-the-building-blocks-of-web-workers-5-cases-when-you-should-use-them-a547c0757f6a