Web Workers

25 Jan 2010 | By Alex Young | Tags tutorials concurrency

When you’re writing JavaScript you typically think in single-threaded and event-based terms. This is fine for most tasks, and event-based programming is a great paradigm for classes of problems we face when writing JavaScript. However, not all problems are best modeled this way so sometimes we need threads.

The Web Workers Specification describes an API for running background scripts. Web Workers introduces the Worker constructor, and it looks like this:

var worker = new Worker('worker.js');

worker.onmessage = function(event) {
  document.getElementById('result').textContent = event.data;
};

The onmessage handler allows your main script to receive messages from the worker. The worker is a separate script. This code will work in Firefox 3.5, Safari, and you can even emulate it using fakeworker.js.

Why?

Experienced JavaScript developers are so used to working without threads that they might question their validity. Well, traditional JavaScript is not parallel. Things that appear parallel are actually single-threaded, sharing execution with timers. This is a problem for long-running tasks: anything that will block on IO or intensive computation is a potential target for concurrency.

The necessity for threads will become more apparent as people write more sophisticated GUIs and games that use multimedia, especially if media needs to be decoded.

Runtime Implementation

How this is implemented by the runtime is completely dependent on the browser. The spec says:

Create a completely separate and parallel execution environment (i.e. a separate thread or process or equivalent construct), and run the rest of these steps asynchronously in that context.

And Mozilla’s implementation is encouraging:

The Worker interface spawns real OS-level threads… Read more in Using web workers

Each worker is run according to the run a worker algorithm.

Termination

Workers can be sent a terminate message to kill them using worker.terminate(). Workers will also be killed when browser windows are closed.

Shared Workers

Shared workers can be created using the SharedWorker constructor. Message ports are used to communicate with workers. The idea is that multiple pages can access the same worker pool.

A Fancy Example

I recently found this fancy Procedural Content Generator which is implemented using Worker(). It renders incredibly quickly in Safari.

Other Resources

John Resig has a post on Web Workers called Computing with JavaScript Web Workers which compares a benchmark against browsers before they had Web Worker.

CommonJS/JSGI: The Emerging JavaScript Application Server Platform covers how server-side JavaScript might adapt Web Workers, based on comments from the CommonJS wiki.


blog comments powered by Disqus