
Web Workers are a powerful feature in modern web development, enabling JavaScript to run concurrently in thebackground without blocking the main user interface thread.
In thetraditional web development model, JavaScript code executes on thesame thread as the user interface. This means that computationally intensive tasks, such as complex calculations, data processing, or network requests, can significantly slow down the user experience. Users may encounterunresponsive web pages or even complete freezes when a script monopolizes the CPU.
Web Workers address this problem by introducing amulti-threaded approach to JavaScript executionwithin the browser. With them, you can create separate threads that run concurrently alongside the main application thread.
Key points to understand Web Workers
File: Web Workers are just JavaScript files loaded by the main thread.
Concurrency: Web Workers provide true concurrency by executing JavaScript code in parallel.
Isolation: Each Web Worker runs in isolation from the main thread and other workers. They have their own global scope, which means they cannot directly access variables or functions defined in the main thread or other workers.
Communication: Communication between workers and the main thread is achieved through message passing (
postMessage
), ensuring data integrity and safety.Background Processing: Web Workers are ideal for offloading resource-intensive operations like data parsing, image processing, or lengthy computations to prevent them from affecting the user experience.
No UI Access: Web Workers are unable to access the Document Object Model (DOM) directly, as they run outside the main thread. This limitation ensures that UI operations remain exclusive to the main thread, preventing potential conflicts and race conditions.
Browser Support: Web Workers arewidely supported in modern browsers, making them a viable technology for a broad range of web applications. However, it's essential to check browser compatibility when implementing aWorker in your projects.
Ok, too much chat... Let's dive into the code as usual!
Web Worker support
First of all. We need to make sure that the browser supports Web Workers. We do this by checking if theWorker
instance is present in the window object:
// index.jsif(!window.Worker){console.log(`Your browser doesn't support Web Workers!`);return;}
Web Worker creation
To use a Web Worker, simply create a new instance of aWorker
, passing theURL of the associatedfile as an argument:
// index.jsconstworker=newWorker('./worker.js');
Prepare the communication with the Web Worker
To "connect" main thread with the Web Worker we need to listen to the messages the Web Worker might send using its exposed methods:
// index.jsworker.onerror=(error)=>{// when an error occurs in the worker};worker.onmessage=(event)=>{// everytime a worker use `postMessage` to send a message}worker.onmessageerror=(event)=>{// e.g. the message from the worker can't be serialized}
Communication
In order to communicate with the web workerfrom the main thread, we just push a message using thepostMessage
method of theWorker
:
// index.jsworker.postMessage({message:'Do something'});
...and inside the worker we listen to themessage
and read thedata
property:
// worker.jsaddEventListener('message',function(event){console.log(event.data);// { message: 'Do something'}})
We can do the other way round by calling thepostMessage
inside the worker:
// worker.jspostMessage({message:'A message from the worker!'});
...and react to the message event in the main thread using theonmessage
method of the worker instance:
// index.jsworker.onmessage=(event)=>{console.log(event.data);// { message: 'A message from the worker!'}}
The whole code
Let's recap the basic code for the two files.
Main thread
// index.jsif(!window.Worker){console.log(`Your browser doesn't support Web Workers!`);return;}constworker=newWorker('./worker.js');worker.onerror=(error)=>{...};worker.onmessage=(event)=>{...}worker.onmessageerror=(event)=>{...}worker.postMessage({message:'Do something'});
Web Worker
// worker.jsaddEventListener('message',function(event){if(event.data==='Do something'){postMessage({message:`Ok, I'll do!`});}else{console.log(`I won't do anything...`);}})
NB:
postMessage
is the only way the Web Worker can comunicate with the main thread and viceversa!
Demo
And as always, can't miss thedemo and open sourceproject on GitHub!
The project guides the user through a series of steps to follow, and the idea is to show thedifference between along-running task performed by themain thread (which blocks the UI) and one performed by aweb worker.
NB:Performances are the same but with the Web Worker the UI is still usable.
Tosimulate a long-running task I used this simple code:
functionlongTask(max){letsum=0;for(leti=0;i<5_000_000_000;i++){sum+=i;}returnsum;}
Top comments(0)
For further actions, you may consider blocking this person and/orreporting abuse