Carrying Out Tasks in the Background with HTML5 Web Workers

Jun 25, 2012
HTML5
107 Shares
By

HTML5 offers a range of improved options for executing JavaScript functions. With Web Workers, you can execute scripts in the background, so that intensive processing need not interfere with the main functionality of your page. Of course this is most useful for complex tasks, but in this tutorial we will demonstrate the basics of using Web Workers with your pages using a simple example.

At the moment the most recent versions of all major browsers, except Internet Explorer, support Web Workers – you can’t rely on them just yet.

Create a Page

Let’s get stuck in and create an HTML5 page using the following outline:

<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">

</script>
</head>
<body>

</body>
</html>

We have our script section ready for the JavaScript code and will also create a separate script in which the Web Worker will run. Add the following elements to the body section of your page:

<input type="button" value="GO!" onclick="startWorking()"/>
<input type="button" value="Stop" onclick="stopWorking()"/>

<p>Here is your random word: <span id="random"></span></p>

Our Web Worker script is going to choose random words to display to the user at specified intervals. Notice that the two buttons for starting and stopping the Web Worker call different functions.

Start the Work

In the script section of your page head, add the outline of the function to start the Web Worker, as specified in your start button click listener:

//Web Worker variable
var myWorker;

//function to start the Web Worker
function startWorking()
{
	//function content here
}

We declare the Worker variable outside the function so that we can refer to it in the stop function as well, which we will do later. Inside the “startWorking” function, first add the following checks to determine whether we have browser support:

//check for browser support
if(typeof(Worker)!=="undefined")
{
	//Web Worker is supported - call the script

}
else
	document.getElementById("random").innerHTML =
		"Oops! Your browser doesn't support this.";

We will add code inside the “if” statement to call the Web Worker script, with the “else” statement executing if support is not present, in which case we simply output an error message to the user. In the “if” statement block, add the following to instantiate the Web Worker:

//instantiate the Web Worker object
if(typeof(myWorker)=="undefined")
	myWorker = new Worker("random_work.js");

Here we specify the name of the script containing our Web Worker code – we will create this soon. After this code, still inside the “if” statement block, add the following, providing instruction for when data is received back from the Web Worker:

//receive data from the Web Worker
myWorker.onmessage = function (event) {
	document.getElementById("random").innerHTML = event.data;
};

Inside the Web Worker script, we will output data that this function can receive. In this case the data will be a random word, which we write into the page. We set the Web Worker “onmessage” property to a function with this instruction in it.

Stop the Work

Now we need to implement the function for stopping work. Add the following after your “startWorking” function:

//function to stop the Web Worker
function stopWorking() {
	//terminate the Web Worker
	myWorker.terminate();
}

We are able to refer to the Web Worker here as we declared it outside both functions.

Create a Script

Now to create our Web Worker script. Create a new file and save it with the name you specified when creating the Web Worker object, “random_work.js” in this case. Inside the script, you can add whatever functionality you want to operate in the background. Here we are going to send randomly selected words back to the page, so let’s first create an array to store them in the new script:

//word array
var words = new Array("apple", "chair", "person",
	"hat", "car", "man", "spider", "computer",
	"table", "door", "house", "cat");

Now we will create a function to choose a word randomly from this array. First we declare a variable to store the index of the chosen word:

//index variable
var randIndex = 0;

Now we create the function outline:

//function to choose random word
function pickWord() {
	//pick a word

}

Inside the function, we want to choose a random index within the scope of the array we created. However, we don’t want the script to choose the same word twice in a row, so we use a “for” loop as follows:

//loop to choose random word
//ensure it is different from last time
for(;;) {
	var newIndex = Math.floor(Math.random()*(words.length));
	//is the word different to the last one chosen
	if(newIndex!=randIndex) {
		//update the variable
		randIndex = newIndex;
		//end the loop
		break;
	}
}

This is an infinite loop, so it will only terminate when the break statement executes. The code first chooses a random integer within the scope of the array (between 0 and 11 since the array has length 12). If the number is not the same as the last one chosen, the code inside the loop updates the “randIndex” variable to reflect it and breaks to stop the loop executing again. If the number is the same as last time, the loop continues executing until it chooses a different one.

Now we can read the word from the array using the chosen index and output it back to the page – after the “for” loop:

//choose word from array
var word = words[randIndex];

//send word back to page
postMessage(word);

When the “postMessage” code executes, the “onmessage” part of your page script will execute in turn, writing the new word into the page markup. Now let’s instruct the script to call the function again after a break – after the “postMessage” call:

//call function again after timeout
setTimeout("pickWord()", 1000);

The function will choose another word after a timeout, sending it to the page again. Finally, let’s call the “pickWord” function to start things off, at the end of your Web Worker script, after the function itself:

//call function
pickWord();

You can now save your HTML file and script file, upload them to a server and test them in the browser. Pressing the start button will cause the Web Worker to begin working, then the stop button will terminate it. You should see a series of randomly selected words from the array appearing within the page.

Note: In some browsers, Web Workers do not function in local pages, only those browsed over a network, so you will need to upload your pages and view them online.

Conclusion

Of course in most cases Web Workers are really suited to more intense processing tasks than choosing a word from an array, but the principle remains the same. If you are planning to use multiple Web Workers with complex processing, you may need to learn about threads and concurrency to create pages that function efficiently.

See it in action here: http://www.developerdrive.com/demo/background_tasks/demo.html

Author: Sue Smith
Sue Smith works as a Web/ software developer and technical writer based in the UK: see benormal.info for details. Sue has written for various clients including Smashing Magazine and Mobiletuts+. She also does a little Android development and some comedy writing.
  • http://www.facebook.com/dazsnow Darryl Snow

    Couldn’t see the ‘postMessage’ function – does it have to do anything special for the worker’s ‘onmessage’ function to run?

  • http://www.cbil360.com/ Web Design Company

    Nice tutorial about carrying out tasks in the background with html5 web workers. HTML5 has change the way of programming by simplifying it.

  • Dominik Werner

    Hum, I’m still searching for a way to prevent my js/html5-based experimental metronome from losing its beat when changing tabs. Could this be a way to achieve it? -> http://nie-wieder.net/metronom/test.html