Efficient Script Yielding

HTML4 (~15ms Timers)
HTML5 (4ms Timers)
Efficient Script Yielding W3C Specification

The W3C Efficient Script Yielding specification defines a means for site developers to yield control flow to the user agent before running script. Web developers may want to use this interface to both allow user agent events and display updates to happen before continuing script execution and to avoid long running script dialogs in certain user agents. Many web pages use the setTimeout method with a specified period of zero to attempt to do the same thing. However, setTimeout enforces a minimum delay, even with a specified period of zero, that isn't uniformly implemented across user agents. Removing this minimum delay from setTimeout runs the risk of causing existing webpages, that have come to rely on the minimum delay, to break by going into a seemingly hung state while also significantly increasing the power consumption of the browser.

Web developers commonly use the setTimeout API to break apart long running JavaScript operations. This approach allows the browser to process outstanding work, such as layouts and paints, and then waits for the specified period of time before calling back into JavaScript. It's an important design pattern when building responsive web applications.

Once the browser has yielded control it relies on an interrupt from the underlying operating system and hardware to receive control and issue the JavaScript callback. Having longer durations between these interrupts allows hardware to enter low power states which significantly decreases power consumption. By default the Microsoft Windows operating system and Intel based processors use 15.6ms resolutions for these interrupts (64 interrupts per second). This allows Intel based processors to enter their lowest power state. For this reason web developers have traditionally only been able to achieve 64 callbacks per second when using setTimeout(0) when using HTML4 browsers including earlier editions of Internet Explorer and Mozilla Firefox.

Over the last two years browsers have attempted to increase the number of callbacks per second that JavaScript developers can receive through the setTimeout and setInterval API's by changing the power conscious Windows system settings and preventing hardware from entering low power states. The HTML5 specification has gone to the extreme of recommending 250 callbacks per second. This high frequency can result in a 40% increase in power consumption, impacting battery life, operating expenses, and the environment. In addition, this approach does not address the core performance problem of improving CPU efficiency and scheduling.

The new setImmediate API, which is semantically comparable to the setTimeout and setInterval API's, was designed by the W3C Web Performance Working Group to address the core performance problem without negatively impacting power consumption. Web developers can use the setImmediate API to break apart long running JavaScript operations and will receive a callback immediately after the browser has processed outstanding work. It's the best of both worlds - the efficiency of native scheduling and the power conservation of low frequencies. Using setImmediate is a great replacement for most cases where developers are intentionally using setTimeout(0) today.

This demo visually sorts 250 items using the Quick Sort algorithm once per callback, making one swap during each browser callback. The more browser callbacks per second the faster the items will be sorted. While this is not how you would efficiently implement a sorting algorithm it's a fun way to visualize the impact of callbacks per second. Try sorting using the HTML4 resolution of 15.6ms per callback, the HTML5 resolution of 4ms per callback, and the new setImmediate approach of immediate callbacks. Special thanks to Erik Kay and Mike Belshe from the Google Chrome engineering team for the quick sort test used to demonstrate the benefits of the new setImmediate API. Additional information can be found online including great articles from Nicholas Zakas.