JavaScript - - By Craig Buckler

How to Use JavaScript Shared Web Workers in HTML5

We recently discussed JavaScript web workers with reference to the “dedicated” variety. If you’ve not read it yet, I suggest you do that first — this article builds on the same concepts.

Web Workers in a Nutshell

A web worker is a single JavaScript file loaded and executed in the background on a separate thread. Dedicated web workers are linked to their creator (the script which loaded the worker). Shared web workers allow any number of scripts to communicate with a single worker.

Shared web workers adhere to the same rules as their dedicated counterparts: no DOM, document or page script access, and limited read-only permission to most window properties. In addition, page scripts may only communicate with shared web workers from the same origin/domain (somesite.com).

Currently, shared web workers are supported in Chrome, Safari and Opera. Firefox 4 and IE9 support may arrive, but don’t bet on it. Shared workers may save resources but they add an extra level of complexity. Expect a few issues, e.g.,

  • DOM2 events (addEventListener) handlers appear to be the most reliable implementation.
  • You’ll almost certainly encounter browser-specific quirks and debugging is difficult. The following code works in the latest version of Chrome, but don’t assume it’ll work in Safari or Opera.

Creating a Shared Web Worker

To create a shared web worker, you pass a JavaScript file name to a new instance of the SharedWorker object:


var worker = new SharedWorker("jsworker.js");

Communicating with a Shared Web Worker

Any of your page scripts can communicate with the shared web worker. Unlike dedicated web workers, you must communicate via a ‘port’ object and attach a message event handler. In addition, you must call the port’s start() method before using the first postMessage():

pagescript.js:


var worker = new SharedWorker("jsworker.js");

worker.port.addEventListener("message", function(e) {
	alert(e.data);
}, false);

worker.port.start();

// post a message to the shared web worker
worker.port.postMessage("Alyssa");

When the web worker script receives the first message from a script, it must attach an event handler to the active port. Under most circumstances, the handler will run its own postMessage() method to return a message to the calling code. Finally, the port’s start() method must also be executed to enable messaging:

jsworker.js:


var connections = 0; // count active connections

self.addEventListener("connect", function (e) {

	var port = e.ports[0];
	connections++;

	port.addEventListener("message", function (e) {
		port.postMessage("Hello " + e.data + " (port #" + connections + ")");
	}, false);

	port.start();

}, false);

Like their dedicated siblings, shared web workers can:

  • load further scripts with importScripts()
  • attach error handlers, and
  • run the port.close() method to prevent further communication on a specific port.

Shared web workers probably won’t be a viable technology for a couple of years, but they raise exciting opportunities for the future of JavaScript development. Let’s hope browser vendors can supply a few decent tracing and debugging tools!

Sponsors