Check out my books on Amazon at https://www.amazon.com/John-Au-Yeung/e/B08FT5NT62
Subscribe to my email list now at http://jauyeung.net/subscribe/
Since most modern browsers are tabbed, it’s possible that a webpage may reside in a tab that stays in the background and not visible to the user.
The Page Visibility API can provide us with insight as to whether a page is visible to the user.
In this article, we’ll look at the Page Visibility API, its use cases, and how to use it.
Visibility Change Event
When a user minimizes the window or switches to another tab, the Page Visibility API sends a visibilitychange
event to let listeners know that the state of the page has changed.
We can handle the event when it’s triggered and do something according to the visibility state. For example, we can pause the video when the page is hidden from view.
The visibility state of an iframe is the same as the parent document that the iframe is in. Hiding an iframe
with CSS doesn’t trigger visibility events or change the state of the document contained within the iframe
.
Use Cases
There’re many use cases for using the API. Some of them include the following:
- pausing an image carousel when the page is hidden
- stop polling the server for information when the page is hidden
- prerendering a page to keep an accurate count of page views
- switch off the sound when the page is not being viewed
Without the Page Visibility API, developers resort to imperfect solutions like listening to the blur or focus events of the window to help detect whether the page is visible or not.
They don’t tell if they’re hidden or not, just whether they’re in focus or not.
Policies that Help Background Page Performance
Most browsers do a few things to help save resources when a page isn’t in view.
requestAnimationFrame
callback won’t be called to improve performance and battery life when a page is in the background.
setTimeout
and other timers are throttles in the background or inactive tabs to improve performance.
Throttling is also done in browsers to limit CPU usage by background tabs.
Each background tab has its own time budget between -150ms and 50ms.
Browser windows are subjected to throttling after 30 seconds in Firefox and 10 seconds in Chrome.
Timer tasks are only permitted when the time budget is non-negative.
Once the timer’s code finishes running, the duration it takes to execute is subtracted from the time budget.
The budget regenerates at a rate of 10ms per second in both Firefox and Chrome.
Some processes ate exempt from throttling behavior. Tabs that are playing audio are considered foreground tabs and aren’t subject to throttling.
Code that uses real-time network connections goes unthrottled to prevent the closing of these connections.
IndexedDB processes are also left unthrottled to avoid timeouts.
The Page Visibility API can let us stop these things manually if we want to do so.
Photo by Oscar Sutton on Unsplash
Using the Page Visibility API
The Page Visibility API is part of the document object.
We can use it by checking the document.hidden
property or the document.visibilityState
property. They’re both read-only.
To watch for changes in both, we can listen to the visibilitychange
event.
To do this we can use the following example. Our example will pause a video when we switch to a different tab. First, we add the HTML code for the video as follows:
<video controls src='https://sample-videos.com/video123/mp4/240/big_buck_bunny_240p_30mb.mp4'></video>
Then in our JavaScript code, we can listen to the visibilitychange
event as follows:
const video = document.querySelector('video');
document.addEventListener('visibilitychange', () => {
if (document.visibilityState !== 'visible') {
video.pause();
}
})
In our event listener callback, we pause the video when the visibilityState
isn’t ‘visible’
, which means the user can’t see the tab either by navigating away from the tab or window, minimizing the window, or turned the screen off.
The alternative to this is to set the event handler to the onvisibilitychange
property of document
.
document.visibilityState
can take on these 3 values:
-
visible
— the page is visible to the user as a foreground tab -
hidden
— the page isn’t visible to the user, either because it’s in the background, or the minimized or the device’s screen is off. -
prerender
— the page is being prerendered and isn’t visible to the user. A document may start in this state, but will never switch to this state from any other state since it can only prerender once. Not all browsers support prerendering. -
unloaded
— the page is being unloaded from memory. Not all browsers support this.
Compatibility
This API has been supported for a while. Chrome since version 33 supports this API. Edge, Firefox, IE 10 or later, and Safari 7 or later all support this API.
Mobile versions of these browsers also support this API.
The Page Visibility API is useful for detecting the visibility state of the page. We can listen to the visibilitychange
event and then get the visibility state with document.visibilityState and so what we want with it.