HTML 5 Web Workers



How to Use HTML5 Web Workers

Hi everyone,

In this tutorial, I am going to introduce you to Web Workers. By the end of this tutorial you will know what it is and how to use it.


Shared Web Workers also exist but I am not covering it in this tutorial

You might have already encountered an error saying that a JavaScript script is taking too much time to run (also called unresponsive script...), why is that?

Well JavaScript runs in a single threaded environment in a browser, so if you have a script which is performing a long task, you have to wait this task to finish its job before doing anything else.

Many browsers might think that something is going wrong if a task is taking too much time and they will propose you to kill the script.

To prevent that, most developers used to break the big task into smaller tasks when possible and use setTimeout or setInterval for instance.

What is a Web Worker?


A worker is a thread, it allows you to do tasks in a background process in parallel of the main browser UI thread.

A worker is a JavaScript file that contains the "task" you want to perform in a separate thread.

Very important thing: You do not have access to the DOM inside a Worker and you do not have access to the page that spawned it.

So what can you access inside a Worker:

  • navigator object
  • location object (read-only)
  • importScripts() method allows you the access to script files in the same domain
  • JavaScript objects such as Object, Array, Date, Math, String
  • XMLHttpRequest
  • setTimeout() and setInterval() methods

 


So how do you communicate with the main thread (the web page you are seeing)?

You communicate by passing messages between the Worker and the web page.

According to the current specification:

 

 

 

Workers (as these background scripts are called herein) are relatively heavy-weight, and are not intended to be used in large numbers.
...
Generally, workers are expected to be long-lived, have a high start-up performance cost, and a high per-instance memory cost.

 


Let us see how this works with a minimalistic example.

This will be your web page that will spawn the Worker, I will provide you a link for all files at the end of the tutorial, I will just focus on what is important:

 

 

 

 

 

Code:
<!DOCTYPE html>
<html>
  <head>
	<meta charset="utf-8" />
	<title>The HTML5 Blog</title>
	<link rel="stylesheet" href="style.css">
    <script>
      window.onload=function() {
	  //Declares a worker
	  var robot=new Worker('robot.js');

	  //Processes message received by the worker
	  robot.onmessage=function(event){
		document.getElementById('msg_from_worker').innerHTML=event.data;
	  };
		  
	  //Defines the click event for the button
          document.getElementById('btn_send').onclick=function() {
		var msg_for_worker = document.getElementById('msg_for_worker').value;
		robot.postMessage(msg_for_worker);
	  };
		  
	};
    </script>
  </head>
  <body>
    ...
    <h3>Have a little chat with our robot</h3>
    <input type="text" id="msg_for_worker"/>
    <input type="button" id="btn_send" value="Send message to the worker" /> <br/>
    <textarea id="msg_from_worker" readonly></textarea>
    ...
  </body>
</html>

 


This part of code is just the UI (nothing really cool or exiting here):

 

 

 

 

Code:
<input type="text" id="msg_for_worker"/>
<input type="button" id="btn_send" value="Send message to the worker" /> <br/>
<textarea id="msg_from_worker" readonly></textarea>

 


Now I'm going to explain what happens on the JavaScript side:

 

 

 

Code:
var robot=new Worker('robot.js');

 


This declares and spawn a new worker and its code is contained in the file "robot.js" (we will discuss the content of this file after).

We said before that the main window and the worker communicate by messages, so how do I process messages coming from the worker?

 

 

 

 

Code:
robot.onmessage=function(event){
  document.getElementById('msg_from_worker').innerHTML=event.data;
};

 


The onmessage event happens when the worker use the postMessage method (in "robot.js").
The actual message is contained in event.data

Finally, how to post messages to the worker?

 

 

 

 

Code:
document.getElementById('btn_send').onclick=function() {
  var msg_for_worker = document.getElementById('msg_for_worker').value;
  robot.postMessage(msg_for_worker);
};

 


To send a message to the worker, you use the postMessage method. It is important to know that messages are copied and not shared when the worker and the page communicate.

Now let us see what is inside "robot.js":

 

 

 

 

Code:
self.onmessage=function(event){
  self.postMessage("You wrote: " + event.data);
};

 


You can notice that the methods and events are the same that we have just used in the web page.

Notice the reference to the worker by using self.

You can also handle errors by using onerror event, It contains three interesting informations:

 

 

 

  • filename: Name of the worker that caused the error
  • lineno: Line number where the error occurred
  • message: The error message

 


How to detect if the browser supports web workers:

 

 

Code:
if (typeof Worker != "undefined")
{
  //Your browser supports web workers
}

 


Note that for the moment, only IE does not support Web Workers.

Also note that because of Chrome security restrictions, you cannot run your app from the file:// scheme unless you start Chrome with the --allow-file-access-from-files flag

Now that you understand Web Workers, you can look at other examples like this one

You can download my files here

 

 

Published September 17, 2010