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!

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

  • Tim

    Let the memory consumption begin! I hope they have some type of garbage collection processes in the browsers to try and avoid potential memory leaks from people not closing the sockets off.

    Can they be used to communicate between browser windows or tabs?

    • http://simon.html5.org/ zcorpan

      “Can they be used to communicate between browser windows or tabs?”

      Yes. But only same-origin. If you want to communicate between windows/tabs, there’s the window.postMessage() API.

  • http://simon.html5.org/ zcorpan

    (Disclaimer: I work for Opera and I did quality assurance of our Web Worker implementation.)

    “DOM2 events (addEventListener) handlers appear to be the most reliable implementation.”

    .onmessage etc listeners work fine in Opera.

    “The following code works in the latest version of Chrome, but don’t assume it’ll work in Safari or Opera.”

    It works fine in Opera. If you know of any bugs, please report them here https://bugs.opera.com/wizard/ Thanks!

    • http://www.optimalworks.net/ Craig Buckler

      Thanks Zcorpan.

      I initially wrote the code above shortly before Opera 11 was released and, for some reason, it failed in Opera 10.6? Or, more specifically, I couldn’t get it working!

      I’m glad the .onmessage listeners work in Opera, although they didn’t appear to in the webkit browsers?

      As mentioned, it’s still early days for shared web workers but it’s great developers can experiment with them now.

  • http://demofox.org Alan

    This article explains how to use shared workers and their caveats with modern browsers, but not anything about why you would use them or their differences from a dedicated web worker. B-!