How to use Web Workers

Web Workers are one of the several technologies introduced with HTML5. But what is JavaScript/Web Workers? Well, as we know Javascript is client-side script that runs in a single thread, that means you can’t run multi tasks at same time. Although many developers like me, “solve” this problem using functions like “setTimeout” or “setInterval”, in fact these functions runs asynchronously, but even so doesn’t mean that are concurrency between each other.

In this article I’m assuming that you have good knowledge in programming in general and in JavaScript in concret.

A Web Worker runs in a isolate or dedicated thread, to create a worker you normally put Worker Code in a separated file, as you can see in the example below:

var myworker = new Worker("myworker.js");

After declared a Worker you need to establish a communication between Worker and its parent page. To do this you must use postMassage method. Through this method you can send data as a simple String or a JSON object. In the example below you can see how you create a Worker, send some message and watch a response from it.

//# app.js 

// create a new Worker object
var myworker = new Worker("myworker.js");

// wacth a message event, it’s triggered when worker send some message
myworker.addEventListener("message", function(e) {
    console.log("Worker sent: "+e.data);
});

// send some information to worker (String/JSON)
 worker.postMessage("Hi Worker, process something for me!");

Now you need define the Worker code (into myworker.js JavaScript file), in the example below you can see a simple code that receives messages from UI thread and return back the same message.

//# myworker.js

// watch the message event, triggered when main thread send some data
self.addEventListener("message", function(e) {
    self.postMessage(e.data);
}, false);

As you can see is very simple to implement Web Workers in JavaScript. Some further details that you need knows:

  • close(), this method is used to stop Worker execution;
  • importSripts(“url_to_js_file”), this method is used into Worker scope to add some extra code or library to your Worker;
  • self or this, both represent the Worker scope;

Because Workers run in a separated process/thread they don’t have access to all Javascript features, they only can access to the following subset:

  • Location object;
  • Navigator object;
  • XMLHttpRequest;
  • setTimeout, clearTimeout;
  • setInterval, clearInterval;

Order Ways to Implement Web Workers

Although I think these aren’t good practices If you don´t want create a file to each Worker that you need, you have alternative ways to make the same result. Let’s show you how to implement a Worker with Blob objects.

 // create a varible with Worker code string
 var workerCode = "self.addEventListener('message', function(e) { self.postMessage('some message'); })";
 
 // create a new Blob object based on Worker code string
 var myblob = new Blob(workerCode );
 
 // get the "URL" to the Blob object
 var blobUrl = window.URL.createObjectURL(myblob);
 
 // create a new Worker object based on Blob object "URL"
 var myworker = new Worker(blobUrl);
 
 // watch the message event
 myworker.addEventListener("message", function(e) {
     console.log(e.data);
 });

 // send a message to Worker
 myworker.postMessage("some message");

Another way to create a worker is putting Worker Code into a script tag and then load it to a Blob object. Let’s see how to implement it.

<script id="myworker" type="javascript/worker">
    // watch the message event
    self.addEventListener("message", function(e) { 
        // send a message to UI/main Thread
        self.postMessage("some message"); 
    });
</script>

// get the script tag content (worker code)
var workerCode = document.getElementById("myworker");

// create a new Blod object based on Worker code
var myblob = new Blob( workerCode );

// get a "URL" to Blod object
var blobUrl = window.URL.createObjectURL(myblob);

// create a new Worker based on Blod object "URL"
var myworker = new Worker(blobUrl);

// watch the message event
myworker.addEventListener(“message”, function(e) {
    console.log(e.data);
}); 

// send a message to Worker
myworker.postMessage("some message");

Conclusion

Well, as you can see Web Worker are a very simple and strong way to implement multi-threading algorithms using JavaScript. Furthermore, you only should use Workers when you need execute algorithms with long execution time, when you need process huge data, when you need obtain data from servers or other specific situations that you need ensure that user never will wait until algorithm is executing.