JavaScript is single threaded, all your code runs on the main thread. Now if you run some CPU intensive task like compressing a large file, the browser will become unresponsive while it performs the task. To overcome this, we use WebWorkers.
WebWorkers are external JavaScript files that run in a separate thread, so that you main thread can remain free to process user input.
As WebWorkers run in separate threads from the main thread, they do not have access to
- The DOM
- The
window
object - The
document
object - The
parent
object
You can import scripts in webworkers using the
importScripts() method
Example: importScripts('script_url_or_path');
Most browsers support WebWorkers , you can see the list of supported browsers here.
There are 2 types of WebWorkers, Dedicated and Shared.
Dedicated worker are only accessible from the script that first spawned it, Shared workers can be accessed from multiple scripts concurrently.
To send and receive data between the webworkers and the main thread, you need to use the PostMessage API .
The PostMessage Api is simple to use:
Send data by calling the postmessage function on the object which you need to send the data to.
object.postMessage('example data') //object is the reference to send the data to.
To listen for data, you can listen for the message listener
self.addEventListener('message', function(e) {
console.log('received data '+e.data);
})
Create a dedicated worker
To create a dedicated webworker, you can use the worker constructor method
var worker = new Worker('worker.js');
you can then use the post message api to send data back and forth to the worker.
You can terminate the worker using the terminate method
w.terminate();
Simple Dedicated WebWorker Example
Lets consider a simple example, in your main javascript, first lets create a web worker called “worker”
var worker = new Worker('worker.js');
Next we tell the worker to start
worker.postMessage({id:'start'});
Next create a file called worker.js , this file will receive data from the main thread, it then creates an array, fills it with 100000 random numbers , sorts it and sends the sorted array back to the main thread.
onmessage = function(e) {
var data = e.data;
if(data.id=="start"){
var arr = [];
var randomInt;
for(var i = 0; i<=100000; i++){
randomInt = Math.floor(Math.random()*1000+1);
arr.push(randomInt);
}
var sorted_arr = arr.sort(function(a, b){return a-b});
postMessage({id:'sorted_array',result:sorted_arr.toString()});}
}
Next in the main thread, we receive the result and display the result in a textarea.
worker.onmessage = function(event) {
var data = event.data;
if(data.id=='sorted_array'){
var result = data.result;
document.getElementById('output').value = result;
}
}
You can find the code for the above example here.