Web Worker in HTML5

We see Web Worker in HTML5: execution of Javascript in multi-threading.

Applications for HTML5 are written -how could it be otherwise- in Javascript. But when compared to other development environments (for example, native to an OS), Javascript has always suffered from an important limitation: its entire execution process is always kept within a single thread.

This may seem simply unusual in a world like today with multi-core processors like the i5/i7 that offer up to 8 logical CPUs, and even with the latest ARM processors for mobile devices, which already have two or even four. cores. Fortunately, we are seeing HTML5 offer the web a better alternative to take advantage of these incredible new processors, which will certainly help to spread a new generation of web applications.

Before Web Workers…

This Javascript limitation means that a long-running process can hang the entire window. It is often said that it “blocks the user interface (UI) thread”. This is the main thread in charge of managing all the visual elements and their related tasks: drawing, screen refresh, animation, user input events, etc.

We all know the painful consequences of overloading this thread: the page crashes and the user can no longer interact with your application. The user experience is, of course, very bad and the user will probably decide to close the browser tab or instance. Definitely the kind of attitude you don’t want for your app.

To avoid this, browsers have implemented a protection mechanism that notifies the user when a script that suspiciously captures machine resources for an excessive period of time is executed.

However, this mechanism is unable to tell the difference between a poorly done script and one that simply takes longer than normal to complete its activity. Still, since the UI thread can block, it’s better to warn the user that something anomalous is probably going on. Here are two examples of this type of message (from Firefox 5 and IE9):

Until now, these problems were rare, mainly for two reasons:

  1. HTML and JavaScript were not used in the same way and for the same purposes as other technologies capable of distributing their tasks over multiple threads. Websites in general offer poorer user experiences compared to native apps.
  2. There are also other ways to solve (more or less well) this concurrency problem.
See also  What is the equivalent of the explode function in Javascript?

These alternatives are well known to all Web developers. For example, we were trying to simulate the execution of tasks in parallel using the setTimeout() and setInterval() methods. HTTP requests can also be executed asynchronously with the help of the XMLHttpRequest object which prevents UI hangs while loading resources from remote servers. Finally, DOM Events allow us to program applications giving the appearance that several things are happening at the same time. Illusion, reality? You are right!

To better understand why, let’s take a look at some kind of Javascript pseudocode and see what happens inside the browser:

Let’s project this code inside a model. This diagram shows us what happens in the browser on a time scale:

This diagram clearly shows the non-parallel nature of our tasks. Rather, the browser is limited to queuing the different execution requests:

  • From 0 to 5 milliseconds: The init() function starts a task that takes about 5 ms. on completion. After 5 ms. the user fires a mouse click event. However, the event cannot be handled at this time since the init() function that currently monopolizes the main thread is still executing. The click event is saved and will be handled at a later time.
  • From 5 to 10 milliseconds: The init() function continues its processing for 5 ms. and then asks to schedule the call to timerTask() at 10ms. This function should, logically, be executed at the 20 ms point. of the time line.
  • From 10 to 15 milliseconds: 5 more milliseconds are needed to finish the execution of the init() function. This is therefore the interval that corresponds to the yellow 15 ms block. As soon as the main thread is freed, it can start dequeuing the saved requests.
  • From 15 to 23 milliseconds: The browser starts executing the handleMouseClock() event which runs for 8 ms. (the blue block).
  • From 23rd to 25th millisecond: As a side effect, the timerTask() function, which was intended to run at the 20th millisecond of the timeline, is shifted by about 3ms. The other scheduled points (30 ms, 40 ms, etc.) are honored since there is no more code capturing CPU resources.
See also  What is AngularJS

All these points don’t really solve the starting problem: everything is executed inside the main UI thread.

But it happens that, despite the fact that Javascript has not been used for the same type of applications as “high-level languages”, this is beginning to change thanks to the new possibilities introduced by HTML5 and its friends. It is therefore more important than ever to give Javascript more power so that it can enable us to create a new generation of applications with parallel processing capabilities. This is precisely what Web Workers were born for.

Web Workers or how something can be executed outside the thread of the User Interface

He defines a way to run scripts in the background. We can, under this specification, execute some tasks in threads that reside outside the main page and therefore do not affect the performance of the rendering task. However, just as we know that not all algorithms can be executed in parallel, not all Javascript code can take advantage of Workers. OK, chitchat, let’s get to know more about who these famous Web Workers are.

My first Web Worker

Since Web Workers run in separate threads, we need to put their code in separate files from the main page. Then we will have to instantiate a Worker object to make the call:

var myHelloWorker = new Worker(‘helloworkers.js’);

Then we can initialize the worker (and with it a thread in Windows), sending it a first message:

myHelloWorker.postMessage();

Obviously, the workers and the main page communicate through messages. These messages can be created with regular strings or JSON objects. As an example of a simple message exchange, let’s start by reviewing a very basic example. It will post a string to a worker that will simply concatenate it with any other string. To do this we add the following code inside the “helloworker.js” file:

function messageHandler(event) {
// Access the data of the message sent by the main page
var messageSent = event.data;
// Prepare the message to be returned
var messageReturned = “Hello ” + messageSent + ” from a different thread!”;
// Post the message back to the front page
this.postMessage(messageReturned);
}

See also  Gradients with CSS 3

// Declare the callback function that will be executed when the main page makes a call to us
this.addEventListener(‘message’, messageHandler, false);

We have simply defined within “helloworkers.js” a small code that will be executed in another thread. You can receive messages from our home page, do something with them, and return another message back to the home page. Then we have to write the receiver code on the main page. This is the complete code with the return message handler:




Hello Web Workers



The result will be: “Hello David from a different thread!”. Awesome huh!

Keep in mind that the worker will be alive until we stop him on command.

Since there is no garbage disposal system, we have to control the state of the workers. And we must keep in mind that instantiating a worker consumes memory… and we must not forget the time it takes for its initial startup. To stop a worker we have two alternatives:

  1. From the main page by calling the terminate() command
  2. From the worker itself using the close() command.

DEMO: You can see this same example with some improvements in your own browser, at:

Post messages using JSON

Obviously, in most cases the workers will exchange more structured data (and by the way, Web Workers can communicate with each other using the message channels.)

But the only way to send structured messages to a worker is by using the JSON format. Fortunately, the browsers that currently support Web Workers are advanced enough to support JSON natively. How wonderful!

Let’s go back to our previous example. We are going to add an object of type WorkerMessage. This type will be used to send some commands with parameters to our “workers”.

Let’s use a simplified version of the HelloWebWorkersJSON_EN.htm web page:




Hello JSON Web Workers


Loading Facebook Comments ...
Loading Disqus Comments ...