Web Workers

Web workers are part of the living standard widely known as HTML5. To create one, you call the global Worker constructor with the URL of a script.

 
var​ worker = ​new​ Worker(​'worker.js'​);
 
worker.addEventListener(​'message'​, ​function​(e) {
 
console.log(e.data); ​// echo whatever was sent by postMessage
 
});

(Usually, we want only the data property from the message event. If we were binding the same event handler to multiple workers, we could use e.target to determine which worker emitted the event.)

So, now we know how to listen to workers. Conveniently, the interface for talking to workers is symmetrical: we use worker.postMessage to send it, and the worker uses self.addEventListener(’message’, ...) to receive it. Here’s a complete example:

 
// master script
 
var​ worker = ​new​ Worker(​'boknows.js'​);
 
worker.addEventListener(​'message'​, ​function​(e) {
 
console.log(e.data);
 
});
 
worker.postMessage(​'football'​);
 
worker.postMessage(​'baseball'​);
 
 
// boknows.js
 
self.addEventListener(​'message'​, ​function​(e) {
 
self.postMessage(​'Bo knows '​ + e.data);
 
});

You can play with the message-passing interface at a little site I created, the Web Worker Sandbox.[46] Any time you create a new example, it gets a unique URL that you can share.

Restrictions on Web Workers

Web workers are primarily intended to handle complex computations without compromising DOM responsiveness. Potential uses include the following:

  • Decoding video as it streams in with the Broadway implementation of the H.264 codec[47]

  • Encrypting communications with the Stanford JavaScript Crypto Library[48]

  • Parsing text in a web-based editor, à la Ace[49]

In fact, Ace already does this by default. When you type code into an Ace-based editor, Ace needs to perform some pretty heavy string analysis before updating the DOM with appropriate syntax highlighting. In modern browsers, that analysis is done on a separate thread, ensuring that the editor remains smooth and responsive.

Typically, the worker will send the result of its computations to the master thread, which will then update the page. Why not update the page directly? Mainly, to keep JavaScript’s async abstractions intact. If a worker could alter the page’s markup, we’d end up in the same place as Java, wrapping our DOM manipulation code in mutexes and semaphores to avoid race conditions.

Likewise, a worker can’t see the global window object or any other object in the master thread (or in other worker threads). When an object is sent through postMessage, it’s transparently serialized and unserialized; think JSON.parse(JSON.stringify(obj)). So, changes to the original object won’t affect the copy in the other thread.

Even the trusty console object isn’t available to workers. All a worker can see is its own global object, called self, and everything bundled with it: standard JavaScript objects like setTimeout and Math, plus the browser’s Ajax methods.

Ah yes, Ajax! A worker can use XMLHttpRequest freely. It can even use WebSocket if the browser supports it. That means the worker can pull data directly from the server. And if we’re dealing with a lot of data (like, say, streaming video that needs to be decoded), keeping it in one thread rather than serializing it with postMessage is a big win.

There’s also a special importScripts function that will (synchronously) load and run the given script(s).

 
importScripts(​'https://raw.github.com/gist/1962739/danika.js'​);

Normally, synchronous loading is a big no-no, but remember that we’re in a secondary thread here. As long as the worker has nothing else to do, blocking is A-OK.

Which Browsers Support Web Workers?

On the desktop, the Web Worker standard has been implemented in Chrome, Firefox, and Safari for a couple of years, and it’s in IE10. Mobile support is spotty as well. The latest iOS Safari supports them, but the latest Android browser doesn’t. At the time of this writing, that translates into 59.12 percent browser support, according to Caniuse.com.[50]

In short, you can’t count on your site’s users having web workers. You can, however, easily write a shim to run the target script normally if window.Worker is unavailable. Web workers are just a performance enhancement after all.

Be careful to test web workers in multiple browsers because there are some critical differences among the implementations. For instance, Firefox allows workers to spawn their own “subworkers,” but Chrome currently doesn’t.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.129.42.244