Parallelism in JavaScript? you might be thinking that we are already doing parallel programming in JavaScript
using setTimeout(), setInterval(), XMLHttpRequest, async/await and event handlers. But that's just not true.
As developers, we have been mimicking parallel programming because of JavaScript's single threading nature using
event loop.
Yes, all of the above techniques are asynchronous and non-blocking. But, that doesn't necessarily mean parallel programming.
JavaScript's asynchronous events are processed after the currently executing script has yielded.
Meet "Web Workers"
Web Workers introduce real parallel programming to JavaScript.
A Web Worker allows you to fire up long-running computationally expensive task(s) which helps the already-congested main thread to spend all of it's time focusing on layout and paint 😃
Understand web worker in renderer process
Where Web Workers goes in a renderer process (a process in chrome, which is responsible
for everything that happens inside a tab):
Every chrome tab has its own renderer process, chrome will also try to have a single renderer process for tabs with the same domain,
if you want to know about how the same renderer process shares one v8 instance, Good luck!
Renderer process creates multiple threads:
Main thread: Handles most of the JavaScript sent to the browser
Just for fun, you can check processes (not only renderer processes) running in chrome by:
Menu(3 verticle dots on top right) > More tools > Task Manager
How to use?
So, whenever we do
new worker thread will be created and code we have in worker.js will run in there.
Communicating with worker
You can't directly call functions that are in the worker thread.
Communication between the main thread and the worker is done via sending and listening to message event.
Example: Finding length of a string:
In index.js
AND
in worker.js
Here, postMessage takes one argument message, that will be available in the delivered event's data key,
value of the message should be supported by structured cloning algorithm.
We'll write a small application that does some intense task using web workers: accept an image and apply filter.
Run in terminal
Html setup:
Script setup:
Okay, what's going on?
This is mostly implementation details of how we are getting the image from the user and storing the values in imageData.
This will create a worker to run the code in worker.js:
Setting up a worker in worker.js:
If you are like me, first intuition you would get is, let's just pass a function to call back to the worker
and get it over with but, you can't pass a function to the web worker, because functions are not supported by
structured cloning algorithm.
We are listening for a message event
Getting the imageData
Filtering the imageData
Sending imageData back to the main thread.
Send a message to the worker:
Here, we are listening for a change in the filter, then sending imageData and which filter to use to the worker.
Listen for the message from worker
We are listening for a message from the worker, then changing the image data in the context.
You can terminate the worker from the main thread by calling worker.terminate()
If you want to terminate from the worker itself you can call the worker's close() function
Upon calling close(), any queued tasks present in the event loop are discarded and the web worker scope is closed.
The web worker is also given no time to clean up, so abruptly terminating a worker may cause memory leaks.
Other web workers
In reality, there are two types of web worker: Dedicated and Shared, for the scope of this post
we only used dedicated workers.
Use cases
Interacting with WebAssembly
Syntax highlighting
Image filtering
Audio/Video analyzing
Processing large number of arrays (For Arrays you can use binary Arrays which are faster to copy)