May 17, 2010
Javascript Web Workers: From Basics to jQuery.Hive
This is long overdue. Also, it should serve as a context for my slides from jQuery Conference, San Francisco 2010 (use the up and down arrow keys to navigate).
Whether or not you’ve read the WHATWG Web Worker spec and are looking for more information about Javascript multi threading OR you already have a rudimentary understanding of Web Workers and simply need more input, I hope to shed some new light on the subject.
I’ll get started with some basic information about Workers:
- The Workers API is originally based on the now deprecated Gears WorkerPool API
- Creates an OS level script execution environment that is capable of scaling across multiple cores when present
- Workers allow web applications to run non-blocking scripts parallel to the main page.
- Allow long-running processes to execute uninterrupted, while keeping the main page responsive.
- Replace the need for breaking up execution with recursive function setTimeout hacks.
Myths, misconceptions and clarifications
- Workers are not intended to be used in large numbers.
- Creation of a new script execution environment is not free from performance expense. One worker will be hardly noticeable, whereas a large number will cause a loss of response in the main window.
- Workers cannot access non-thread safe content, this means: the
window and document objects or any part of the DOM directly (elements, et al.)
- Workers can only pass data in and out of a thread through the postMessage() API and onMessage Event.
Why you don't get it and Why you don't care
- Web developers aren't used to the concept of multi-threading, because until now, the concept hasn't applied to us
- Support is limited to: Firefox 3.5+, Safari 4+ and Chrome 4+
Got all that? Great! Now let's look at the API
The first thing we need to establish is the new WorkerGlobalScope which is your thread's script execution environment. It's kind of like the window, but is actually the "global scope" of the worker. This parallel dimension exists within the file you passed to the new Worker('worker-javascript-file.js') constructor.
The easiest way to contextualize the worker thread is to think of your main window as the initial worker (as it IS a script execution environment) and the Worker API let's you make "windows" in terms of script execution, in parallel, but with some limitations.
Here's what's new in the window object (main window execution):
The new WorkerGlobalScope has it's own new API as well:
The window and the workerglobalscope BOTH have a postMessage() function and an onmessage event.This is how they communicate.
...and give it try. (Requires a javascript console to see the results)
You'll notice that I've used the progressive approach with addEventListener() instead of onmessage = function () {} - I've done so because I don't believe we should be writing attribute event handlers on worker objects as we once did with elements in the DOM. I also take a strong opposition to Web Worker "tutorials" that use this syntactic approach.
*Edit*
In the time since this was originally published, Chrome, Safari & Opera now support complex JSON messages.
This entry was posted by
Rick Waldron
on May 17, 2010
in Chromium, Firefox, HTML5, JavaScript, jQuery, jQuery Plugins, jQuery.Hive, PollenJS and Web Workers.