Using HTML5 Web Workers to have background computational power

When performing advanced load-heavy operations in a web browser, both the web page it is run in as well as the web browser UI becomes unresponsive till it’s finished. However, there’s a way to address that with HTML5 Web Workers.

What they do

Basically, Web Workers offers you a possibility to load a JavaScript file dynamically and then have it process code in a background process, not affecting the user interface and its response level. You can continue to do whatever you want, selecting thing, clicking etc, while all Web Worker computation is in the background.

Working with it

First, you create a Worker object. Then you can send text data to it with a postMessage method, it can send information back with its own postMessage and both of them have onmessage event handlers to receive data. For instance, here you have a simple example where you send in some data to a Web Worker, have it do 1 000 000 iterations in a loop, and continually post the current value back:

In the web page

	// Creates a Web Worker
	var worker = new Worker("worker.js");
	
	// Posts a message to the Web Worker
	worker.postMessage(0);
	
	// Triggered by postMessage in the Web Worker
	worker.onmessage = function (evt) {
		// evt.data is the values from the Web Worker
		alert(evt.data);
	};

	// If the Web Worker throws an error
	worker.onerror = function (evt) {
		alert(evt.data);	
	};

In the Web Worker JavaScript file

	// Triggered by postMessage in the page
	onmessage = function (evt) {
		// evt.data will be 0 here from the above postMessage
		for (var i=evt.data, il=1000001; i<il; i++) {
			// Continually sends data back
			postMessage(i);
		};
	};

In addition to the postMessage method and the onmessage event used above, there is a handy terminate method on the Worker object, to instantly stop all of its work.

This demo and complete code is available in the HTML5 Web Worker Demo page, which is part of my HTML5 – Information and samples for HTML5 and related APIs playground.

Web Browser support

So far, Web Workers are supported in Firefox 3.5+ and Safari 4, and soon upcoming in Google Chrome.

Issues

All of this is quite nice for heavy operations. However, there are to main issues related to the terminate method:

Firefox and execution of terminate

As you can see in the HTML5 Web Worker Demo, in Firefox, if you click on the “Stop Worker” button, it isn’t actually called till the previous ongoing operation is finished. To me, this practically renders it useless since the whole idea of the terminate method is supposed to be instant, and which seems to be the idea according to the Mozilla Web Worker documentation for terminate():

If you need to immediately terminate a running worker, you can do so by calling the worker’s terminate() method… The worker thread is killed immediately without an opportunity to complete its operations or clean up after itself.

My take is that this is a bug, and I will talk to Mozilla about this.

Can’t restart a terminated Web Worker

In both Firefox and Safari, if you have called the terminate method on a Web Worker, there’s no way to get it started again by calling postMessage on it. Instead, you need to reinstantiate the Worker with the new Worker("filename.js") again, which sort of defeats the idea of pausing/playing a Worker’s action. I don’t know if this is due to design or implementation, but if you craft your code cleverly, you can work around this.

Spreading the load

Despite the issues I think Web Workers are great, and they could prove fantastic in terms of relieving the user interface from being frozen when having to do complex calculations and similar.

14 Comments

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>