Using the Page Visibility API

The page visibility API is an experimental implementation of the webperf WG’s proposed page visibility API in new versions of Chrome (starting in version 13). It allows sites to detect whether they are being displayed to the user.

Why you’d use it

With tabbed browsing, there’s a reasonable chance that any given web page is in the background and thus not visible to the user. Some sites might want to behave differently in such a case. A few examples:

  • A site has an image carousel that shouldn’t advance to the next slide unless the user is viewing the page
  • An application showing a dashboard of information doesn’t want to poll the server for updates when the page isn’t visible
  • A page wants to detect when it is being prerendered so it can keep accurate count of pageviews

Developers have historically used imperfect proxies to detect this. For example, registering an onblur/onfocus handler on the window helps you know when your page is not the active page, but it does not tell you that your page is hidden to the user. Chrome’s experimental prerender feature also means that there are new cases where visibility might be important.

Important: This is an experimental API and may change—or even be removed—in the future, especially as the Page Visibility API standard, which is an early draft, evolves. Check this page for updates to this API.

Detecting the page’s visibility state

Document has two additional properties that you can query: document.webkitHidden and document.webkitVisibilityState.


Returns true if the page is in a state considered to be hidden to the user, and false otherwise.

This property is the preferred way to detect whether the document is visible, although it is merely a convenience property for information returned by document.webkitVisibilityState. The list of values that webkitVisibilityState returns may grow over time, whereas the semantics of webkitHidden will remain the same.

Note that document.webkitHidden will return undefined in browsers that do not support this API. Because undefined is a false-y value, using webkitHidden in a boolean expression allows it to default to meaning "visible" in all browsers.


Returns a string denoting the visibility state of the document.

Possible return values:

The page content may be at least partially visible. In practice this means that the page is the foreground tab of a non-minimized window.
The page content is not visible to the user. In practice this means that the document is either a background tab or part of a minimized window.
The page content is being prerendered and is not visible to the user (considered hidden for purposes of document.webkitVisible). The document may start in this state, but will never transition to it from another value.

There may be more possible return values in the future.

Use this property only if you care about the specific reason why the document is not visible. Otherwise, use the simpler and more general document.webkitHidden.

Note: This API, as designed, may return a false positive for "visible" (reporting that the document is visible when it is in fact not visible), but will never return a false negative (reporting that the document is hidden when it actually is not). For example, the API would report that the document is visible if it is the foreground tab in a window that is not minimized but is fully obscured by another window.

You can test whether the browser supports this API by checking if document.webkitVisibilityState is not undefined.

Detecting when visibility changes

When the document’s webkitVisibilityState changes, an event is fired at the document.


A simple event, fired at the document object immediately after document.visibilityState transitions between visibility states.

Note that visibility has nothing to do with whether the document’s contents have fully loaded, which implies that for any given visibility transition event, onload may or may not have already fired. In addition, webkitvisibilitychange will not fire at all if the page is opened in the foreground and is not prerendered.


Only perform an expensive physics simulation when the page is visible

//startSimulation and pauseSimulation defined elsewhere

function handleVisibilityChange() {
  if (document.webkitHidden) {
  } else {

document.addEventListener("webkitvisibilitychange", handleVisibilityChange, false);

 * If this is a browser that doesn’t support this API, we should
 * start the simulation as soon as this part of the script executes.
 * If it does support the API, then we should start if we’re already
 * visible at this point.  Otherwise, we’ll wait until we’re told
 * that we should start.
 * Browsers that don't support this API will return undefined (a false-y
 * value) for document.webkitHidden, effectively defaulting to visible.
  if (!document.webkitHidden) startSimulation(); 

Only count a pageview after a document is no longer prerendering

var isPrerendering = false;

function handleVisibilityChange(evt) {
  if (!isPrerendering) return;
  isPrerendering = false;

 * We can count the view right now if the document isn't being prerendered.
 * Browsers that don't support the API will return undefined for
 * webkitVisibilityState.
if (document.webkitVisibilityState != "prerender") {
} else {
  //We'll need to count the pageview later
  isPrerendering = true;
  document.addEventListener("webkitvisibilitychange", handleVisibilityChange, false);

Only count a pageview after the document is finished loading AND the document is done prerendering

var viewCounted = false;

function handleVisibilityChange(evt) {
  //Only count the view once we're done prerendering AND the document is done loading
  if (document.webkitVisibilityState == 'prerender'
      || document.readyState != 'complete' || viewCounted)

   * Implementation of view counting system here

  viewCounted = true;

//We'll call checkCountView on load no matter what.
window.addEventListener('load', handleVisibilityChange, false);

if (document.webkitVisibilityState == 'prerender') {
  document.addEventListener('webkitvisibilitychange', handleVisibilityChange, false);


The page visibility API is being standardized by the webperf standards group. You can find the current version of the specification at http://www.w3.org/TR/2011/WD-page-visibility-20110602/.