Efficient Script Yielding - First Editors Draft

One of the deliverables that we took on as part of the expanded Web Performance Working Group was to find a way to allow javascript applications to more efficiently yield control to the host (browser) and receive immediate callbacks when the host has completed processing pending work (for example handling user input of document layouts).

We had the action item to summarize the motivations for the Efficient Script Yielding deliverable, which we're doing through this email, and to publish the first editors draft which can be found here: http://dvcs.w3.org/hg/webperf/raw-file/tip/specs/setImmediate/Overview.html

As the working group has discussed, we believe there's an opportunity for a new API that allows the web developers to (1) efficiently use the CPU without wasted cycles, (2) efficiently use the CPU in bursts to conserve power, (3) improve performance for end user scenarios, and (4) feels familiar to current API's and programming patterns.

Today we see setTimeout and setInterval used for three primary patterns:

1)      Scheduling distant future callbacks (at least 500ms)

2)      JavaScript Based Animation

3)      Breaking apart long running scripts.

We think about #1 as the cases where the current setTimeout pattern works well. For example, you may want to update stock quotes or check for new email on a regular schedule. The problems with #2 are well understood and the working group has a great proposal in place with requestAnimationFrame. The "efficient yielding" deliverable is intended to more efficiently solve scenario #3.

Today, browsers don't process events while long running scripts are executing. This includes everything from UI updates, to user input, to end user features like spell checking. Even though the JavaScript may be manipulating the DOM or updating styles, these updates aren't presented to the user until after the script yields. To allow applications to remain responsive and to process visual changes, web developers are forced to sprinkle setTimeouts throughout their code allowing the browser to process pending work and then call script back at a future time.

The setTimeout callback frequency on Windows has traditionally been around 64 callbacks a second which aligns with the 15.6ms timer frequency. The HTML5 specification recommends 250 callbacks a second which means a 4ms timer frequency. This positively improves the perceived performance around pattern #3 however it comes at the cost of actual performance (interference) and more importantly power consumption. We've measured this extensively on Windows and decreasing the timer frequency from 15.6ms to 4ms impacts battery life by around 22% for common customer scenarios. This is a hardware factor and not specific to Windows. And as we consider forward looking hardware trends we expect this to become more of an issue.

Decreasing timer resolutions may help with some patterns, however it doesn't fully solve the underlying problem. If you think about the bubble sorting example, a developer doesn't actually know how long a single pass will take. To keep the browser responsive they yield frequently, often during each sorting pass. If a modern script engine can perform that pass in 1ms that means 3ms or 75% of the CPU time are wasted and not available to the web developer.

That's why we believe there's an opportunity for an API that allows the web developers to (1) efficiently use the CPU without wasted cycles, (2) efficiently use the CPU in bursts to conserve power, (3) improve performance for end user scenarios, and (4) feels familiar to current API's and programming patterns.

There has been a lot of discussion in the web community and ECMA working groups around the future of the javascript language and the possibility of moving the event queue into the javascript runtime itself. Those are interesting discussions however forward looking and outside the prevue of this deliverable. We would like to leave the larger discussion for the experts on the ECMA side and focus this discussion around a targeted API that will solve the immediate problem and fit well into the HTML4/HTML5 patterns of today.

Here's the first draft of what a "setImmediate" API may look like. We know a few people have expressed concerns around the API name. The "set" portion of the name follows the setTimeout and setInterval naming conventions, and the "Immediate" portion was intended to communicate the immediate nature of the callback. This feels like a good initial name which we validated doesn't have compatibility implications across the top 1 million sites. We expect to iterate on the name based on feedback as the design evolves.

We're looking forward to your thoughts on the first draft.

As an aside, we now have drafts for all three of the new API's we brought into the performance working group charter this spring. It's cool to see Page Visibility,  Request Animation Frame, and Efficient Script Yielding all starting to come together. Congratulations everyone.

Jatinder and Jason

Received on Tuesday, 28 June 2011 22:17:45 UTC