Skip to content

Commit

Permalink
Move implementation notes into new-and-improved README.
Browse files Browse the repository at this point in the history
  • Loading branch information
domenic committed Dec 31, 2012
1 parent 903179e commit 5f4dbfd
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 23 deletions.
76 changes: 64 additions & 12 deletions README.md
@@ -1,26 +1,75 @@
setImmediate.js
===============
# setImmediate.js
**A NobleJS production**

Introduction
------------
## Introduction

A highly cross-browser implementation of the `setImmediate` and `clearImmediate` APIs, currently a
[W3C draft spec][spec] from the Web Performance Working Group. Allows scripts to yield to the browser, executing a
given operation asynchronously, in a manner that is typically more efficient and consumes less power than the usual
`setTimeout(..., 0)` pattern.
**setImmediate.js** is a highly cross-browser implementation of the `setImmediate` and `clearImmediate` APIs, currently
a [W3C draft spec][spec] from the Web Performance Working Group. `setImmediate` allows scripts to yield to the browser,
executing a given operation asynchronously, in a manner that is typically more efficient and consumes less power than
the usual `setTimeout(..., 0)` pattern.

Runs at "full speed" in the following browsers, using various clever tricks:
setImmediate.js runs at full speed in the following browsers and environments, using various clever tricks:

* Internet Explorer 6+
* Firefox 3+
* WebKit (exact cutoff unknown)
* WebKit
* Opera 9.5+
* Node.js
* Web workers in browsers that support `MessageChannel`, which I can't find solid info on.

In all other browsers we fall back to using `setTimeout`, so it's always safe to use.

Reference pages
---------------
## The Tricks

### `process.nextTick`

In Node.js versions below 0.9, `setImmediate` is not available, but [`process.nextTick`][nextTIck] is, so we use it to
shim support for a global `setImmediate`. In Node.js 0.9 and above, `setImmediate` is available.

Note that we check for *actual* Node.js environments, not emulated ones like those produced by browserify or similar.
Such emulated environments often already include a `process.nextTick` shim that's not as browser-compatible as
setImmediate.js.

### `postMessage`

In Firefox 3+, Internet Explorer 9+, all modern WebKit browsers, and Opera 9.5+, [`postMessage`][postMessage] is
available and provides a good way to queue tasks on the event loop. It's quite the abuse, using a cross-document
messaging protocol within the same document simply to get access to the event loop task queue, but until there are
native implementations, this is the best option.

Note that Internet Explorer 8 includes a synchronous version of `postMessage`. We detect this, or any other such
synchronous implementation, and fall back to another trick.

### `MessageChannel`

Unfortunately, `postMessage` has completely different semantics inside web workers, and so cannot be used there. So we
turn to [`MessageChannel`][MessageChannel], which has worse browser support, but does work inside a web worker.

### `<script> onreadystatechange`

For our last trick, we pull something out to make things fast in Internet Explorer versions 6 through 8: namely,
creating a `<script>` element and firing our calls in its `onreadystatechange` event. This does execute in a future
turn of the event loop, and is also faster than `setTimeout(…, 0)`, so hey, why not?

## Usage

In the browser, include it with a `<script>` tag; pretty simple.

In Node.js, do

```
npm install setimmediate
```

then

```js
require("setimmediate");
```

somewhere early in your app; it attaches to the global.

## Reference and Reading

* [Efficient Script Yielding W3C Editor's Draft][spec]
* [W3C mailing list post introducing the specification][list-post]
Expand All @@ -32,3 +81,6 @@ Reference pages
[list-post]: http://lists.w3.org/Archives/Public/public-web-perf/2011Jun/0100.html
[demo]: http://ie.microsoft.com/testdrive/Performance/setImmediateSorting/Default.html
[ncz]: http://www.nczonline.net/blog/2011/09/19/script-yielding-with-setimmediate/
[nextTick]: http://nodejs.org/docs/v0.8.16/api/process.html#process_process_nexttick_callback
[postMessage]: http://www.whatwg.org/specs/web-apps/current-work/multipage/web-messaging.html#posting-messages
[MessageChannel]: http://www.whatwg.org/specs/web-apps/current-work/multipage/web-messaging.html#channel-messaging
11 changes: 0 additions & 11 deletions setImmediate.js
@@ -1,14 +1,3 @@
/* A cross-browser setImmediate and clearImmediate:
* https://dvcs.w3.org/hg/webperf/raw-file/tip/specs/setImmediate/Overview.html
* Uses one of the following implementations:
* - `process.nextTick` in Node < 0.9
* - postMessage in Firefox 3+, Internet Explorer 9+, WebKit, and Opera 9.5+
* - MessageChannel in web workers, in WebKit and Opera
* - <script> element onreadystatechange in Internet Explorer 6–8
* - setTimeout(..., 0) in all other browsers
* In other words, setImmediate and clearImmediate are safe in all browsers.
*/

(function (global, undefined) {
"use strict";

Expand Down

0 comments on commit 5f4dbfd

Please sign in to comment.