Using PC Hardware more efficiently in HTML5: New Web Performance APIs, Part 2


Web developers need API’s to efficiently take advantage of modern PC hardware through
HTML5, improving the performance of Web applications, the power efficiency of the
Web platform, and the resulting customer experience. The second
IE10 Platform Preview
supports emerging API’s from the
W3C Web Performance Working Group
which enable developers to make the
most of the underlying hardware and use battery power more efficiently. This post
details how to use
Page Visibility
, one of the emerging API’s, for better performance and power
efficiency.

Page Visibility: adjust work depending on if the user is looking

Knowing whether a page is visible makes it possible for a developer to make better
decisions about what the page does, especially around power usage and background
tasks. Take a look at the Page Visibility
Test Drive
to see how a Web application can be aware of whether the page
is visible or not to the user.

Screen shot of Page Visibility API test drive demo
The Page Visibility API is now available through vendor prefixed implementations in IE10 and Chrome 13.

The developer can adjust or scale back what work the page does based on visibility.
For example, if a Web based email client is visible, it may check the server for
new mail every few seconds. When hidden it might scale checking email to every few
minutes. Other examples include a puzzle application that can be paused when the
user no longer has the game visible or showing ads only if the page is visible to
the user.

The Page Visibility specification enables developers to determine the current visibility
of a document and be notified of visibility changes. It consists of two properties
and an event:

  • document.hidden: A boolean that describes whether the page is visible or not.
  • document.visibilityState: An attribute that returns the detailed page visibility
    state, e.g., PAGE_VISIBLE, PAGE_PREVIEW, etc.
  • visibilitychange: An event that gets fired any time the visibility state of the
    page changes.

IE10 has prefixed these attributes and event with the ‘ms’ vendor prefix.

With this interface, Web applications may choose to alter behavior based on whether
they are visible to the user or not. For example, the following JavaScript shows
a theoretical Web based email client checking for new emails every second without
knowledge of the Page Visibility:

<!DOCTYPE html>

<html>

<head>

<title>Typical setInterval Pattern</title>

<script>

var timer = 0;

var PERIOD = 1000; // check for mail every second

 

function onLoad() {

timer = setInterval(checkEmail, PERIOD);

}

 

function checkEmail() {

debugMessage("Checking email at " + new Date().toTimeString());

}

 

function debugMessage(s) {

var p = document.createElement("p");

p.appendChild(document.createTextNode(s));

document.body.appendChild(p);

}

</script>

</head>

<body onload="onLoad()">

</body>

</html>

Using Page Visibility, the same page can throttle back how often it checks email
when the page is not visible:

<!DOCTYPE html>

<html>

<head>

<title>Visibility API Example</title>

<script>

var timer = 0;

var PERIOD_VISIBLE = 1000; // 1 second

var PERIOD_NOT_VISIBLE = 10000; // 10 seconds

var vendorHidden, vendorVisibilitychange;

 

function detectHiddenFeature() {

// draft standard implementation

if (typeof document.hidden != "undefined") {

vendorHidden = "hidden";

vendorVisibilitychange = "visibilitychange";

return true;

}

 

// IE10 prefixed implementation

if (typeof document.msHidden != "undefined") {

vendorHidden = "msHidden";

vendorVisibilitychange = "msvisibilitychange";

return true;

}

 

// Chrome 13 prefixed implementation

if (typeof document.webkitHidden != "undefined") {

vendorHidden = "webkitHidden";

vendorVisibilitychange = "webkitvisibilitychange";

return true;

}

 

// feature is not supported

return false;

}

 

function onLoad() {

// if the document.hidden feature is supported, vary interval based on visibility.

// otherwise, just use setInterval with a fixed time.

if (detectHiddenFeature()) {

timer = setInterval(checkEmail, document[vendorHidden] ? PERIOD_NOT_VISIBLE : PERIOD_VISIBLE);

document.addEventListener(vendorVisibilitychange, visibilityChanged);

}

else {

timer = setInterval(checkEmail, PERIOD_VISIBLE);

}

}

 

function checkEmail() {

debugMessage("Checking email at " + new Date().toTimeString());

}

 

function visibilityChanged() {

clearTimeout(timer);

timer = setInterval(checkEmail, document[vendorHidden] ? PERIOD_NOT_VISIBLE : PERIOD_VISIBLE);

debugMessage("Going " + (document[vendorHidden] ? "not " : "") + "visible at " + new Date().toTimeString());

}

 

function debugMessage(s) {

var p = document.createElement("p");

p.appendChild(document.createTextNode(s));

document.body.appendChild(p);

}

</script>

</head>

<body onload="onLoad()">

</body>

</html>

With the Page Visibility API, Web developers can create more power conscious Web
applications. To learn about other emerging API from the
W3C Web Performance Working Group
supported in the second IE10 Platform
Preview, read my post on the requestAnimationFrame API (link).

—Jatinder Mann, Internet Explorer Program Manager

Comments (19)

  1. Anonymous says:

    Hmm… if the draft changes then it might break this code even when there is a prefixed variant that works the "old" way?

  2. Anonymous says:

    I can't get it, if IE10 will follow the HTML5 standards, then why we need to use the "ms" vendor prefix.

    It will be more easier to use the same attributes and events across all the web browsers.

  3. Anonymous says:

    Very good idea, yet the IE10 is easily tricked to think that page is visible, while its not. Hopefuly, that would be fixed before release.

  4. Anonymous says:

    @Tariq:

    Until the draft becomes a Candidate Recommendation, it's better to assume that any implementations are vendor extensions. This is because drafts could change at any time.

    If they implemented a draft spec without prefixing (and then the draft changes), you would have to rely on browser-sniffing rather than feature detection to work out if you can use it.

  5. Anonymous says:

    IE Team

    .jxr(JPEGXR) Filename extension image file support!

  6. Anonymous says:

    Seems like I am not the only one remarking on this: lists.webkit.org/…/017537.html

  7. Anonymous says:

    IE team please build the very basic ability to queue downloads/download only certain number of files at a time to the IE download manager in IE10. Downloading many medium sized files is a total pain as you have to manually start every download, then pause them individually, then resume them one by one. If there is a registry setting somewhere to control maximum number of downloads at a time, please document it in a KB article.

  8. Anonymous says:

    @Björn

    I'm sorry but that argument makes no sense, the code is coded for how it currently works.  How exactly are you supposed to provide code for something that doesn't exist yet?  Of course they all work the same now, but in the future you could do them differently if things change for the non-prefxed version.

  9. Anonymous says:

    I create Visibility.js library to autodetect prefix and add nice syntax sugar: github.com/…/visibility.js

  10. Anonymous says:

    Do you guys know that PC World just posted an article that tells people not to use IE unless they have to?

  11. Anonymous says:

    @ Prior Semblance: Exactly! Nobody knows how the non-prefixed version might look like and behave they shouldn't provide code for it and esp. not with a higher priority than the prefixed versions.

  12. Anonymous says:

    Hi ieblog, is there any ongoing draft about this scenario: "If textarea has wrap=hard (if applicable) and the language is proportional (unlike courier), then there must be an explicit way to find out the row number where the cursor is present. In other words, to find out the rows consumed by the user, not by specifically pressing enter but may be by entering long string, longer than the width of the textarea." <- this is required if we need to capture text from the user and filling it in a fixed size box. Using JS, I have made a workaround by setting the equal size of textarea as of the target content-holder and using same font-family&size (stackoverflow.com/…/253011), but it’s certainly very costly in terms of time complexity.

    Also, what's the ETA on innerHTML for select tag? Is the context awareness problem (for select tag) resolved yet?

  13. Anonymous says:

    @hdmi: people shouldn't read PC World unless they reall have to (like, if they're dumb or something).

  14. Anonymous says:

    Hi MSFT IE Team, could we please have the option for a separate search bar in IE9? While you're at it, can you also re-add the quick-list view. K Thx.

    Sent from Google Chrome because IE9 sucks real hard.

  15. Anonymous says:

    It is frustrating to see such sloppy code formatting.

    //correct formatting

    if(condition){

     //do stuff

    } else {

     //do other stuff

    }

    your code with stuff like this is painful to read:

    else {

  16. Anonymous says:

    I personally like else on its own line, because it looks less messy. Each company has its own style guidelines, so does each person. There is no such thing as "correct formatting".

  17. Anonymous says:

    @please fix your code samples – For me, it's easiest to read when formatted like this:

    if (condition) {

       // do things

    }

    else {

       // do other things

    }

  18. willpeavy.com says:

    @MSFT IE Team should listen to their users – "could we please have the option for a separate search bar in IE9"

    The option to set the address bar and tabs on separate rows has been in place since IE9 was in Release Candidate status.

  19. Anonymous says:

    @please fix your code samples : everybody format their code like they want. But your way of doing it is weird. You should code in TCL, you'll be so happy with this language because you'll be forced to format your code as you like.

    In TCL: "incorrect" formatting = error, so for me it's a bad language.