The Page Visibility API is one of those unflashy, yet extremely useful functionalities. In my case, I used it to prevent certain animations from consuming CPU when the user switched tabs. Since then, I consider it essential in any project involving timers, multimedia, or frequent server requests.
For example, I use it on the Academia website for the book viewer; when the user LEAVES the tab for another, I take the opportunity to save the state.
In this guide, I'll explain what it is, how it works, and how to implement it with practical examples based on my own experience.
The Page Visibility API allows you to know when a web page is being viewed by the user, and therefore, we can make configurations to avoid the use of unnecessary resources once the user is not visiting the page in question; the following image indicates which pages are being viewed and which are not:

That is, when the user moves to another tab or minimizes the window, an event called visibilitychange is triggered to indicate that the page is not being viewed (hidden); this can be quite useful for customizing sections of the web page; for example, the one presented by MDN.
In this post, we will explain how to use the Page Visibility API, which is one of the other JavaScript APIs we've covered in DesarrolloLibre:
- Geolocation with JavaScript
- The Vibration API in HTML5
- The Battery API in HTML5
- Introduction to Notifications in JavaScript
What the Page Visibility API is and what it's for
The Page Visibility API allows you to know if your page is:
- visible
- partially visible
- hidden
- or rendering in the background
This information allows you to optimize resources, improve performance, and avoid unnecessary behaviors when the user isn't viewing your page.
How the visibility change works
Every time the user:
- changes tabs
- minimizes the window
- locks the device
- or opens another window on top
…the browser fires the visibilitychange event.
When I first tested this API, I confirmed something curious: the event is not fired when the window loses focus, only when the page truly stops being visible.
Differences between document.hidden and visibilityState
- Property Type What it indicates
- document.hidden boolean true if the page is hidden
- document.visibilityState string visible / hidden / prerender / unloaded
When to use this API: real optimization cases
This API is ideal in any workflow where you want to save resources without breaking the browser's logic or the user experience.
Pause animations, carousels, or video
In one of my projects, I paused an image carousel. Without this API, the carousel continued advancing even when the user had the tab hidden, wasting CPU.
Reduce server requests when the user is away
If your page queries an endpoint every X seconds, you can:
- pause the requests when it is hidden
- resume them when it becomes visible again
This reduces the load on your backend and improves the experience.
Improve mobile battery consumption
Google emphasizes this: the API helps extend battery life on mobile devices by stopping processes that are not on screen.
In my case, I noticed that on older phones, some animations notably reduced battery life if they weren't paused.
The Page Visibility API in practice: available properties and states
In this part, we will introduce the use of the API by explaining its main components.
The visibilityState enum type can return:
- visible: the page is on screen
- hidden: completely hidden
- prerender: the browser preloads the document
- unloaded: state prior to document unload
Prefixes and current compatibility
Nowadays, prefixes are hardly used, except in older Android browsers.
But for legacy projects, here's the correct way to detect them:
function getHiddenProperty(prefix) {
return prefix ? prefix + 'Hidden' : 'hidden';
}Accessing the Page Visibility API in JavaScript
The document.hidden property allows access to the Page Visibility API; however, due to the large number of browsers and their versions, some may not support this API or it may be necessary to use prefixes:
document.addEventListener('visibilitychange', () => {
if (document.hidden) {
console.log('La página está oculta.');
} else {
console.log('La página es visible.');
}
});The following function allows you to verify if the browser supports the Page Visibility API and obtain its prefix if it requires one; it can be easily adapted for any of the JavaScript APIs:
function getPrefix() {
// check if the browser supports the default prefix if
if ('hidden' in document)
return NULL;
// other possible prefixes var
var prefixes = [ 'moz', 'ms', 'o', 'webkit' ];
for (var i = 0; i < prefixes.length; i++) {
var testPrefix = prefixes[i] + 'Hidden';
if (testPrefix in document)
return prefixes[i]; // retornamos el prefijo
}
// not support
return NULL;
}Once we have the browser's prefix to access the API, we can gain access to the property in question using the following function which receives the previously obtained prefix as a parameter:
// Get the property
function getHiddenProperty(prefix) {
if (prefix) {
return prefix + 'Hidden';
} else {
return 'hidden';
}
} Page Visibility API Events
Using the prefix obtained in the previously defined function again, we get the visibilitychange event in its variation dependent on the browser used:
// Get the prefix to access the visibilitychange event
function getVisibilityEvent(prefix) {
if (prefix) {
return prefix + 'visibilitychange';
} else {
return 'visibilitychange';
}
}Applied example with business logic
In one of my projects:
- It paused a video
- It stopped a timer
- It saved the last visible state
document.addEventListener('visibilitychange', () => {
if (document.visibilityState === "hidden") {
pauseVideo();
stopTimer();
} else {
resumeVideo();
startTimer();
}
});You can see a final example that puts everything discussed so far into practice:
Frequently Asked Questions (FAQ)
- Are document.hidden and visibilityState the same?
- No. One is boolean, the other returns a more specific state.
- Does the visibilitychange event work on mobile?
- Yes, and in many cases it is even more useful than on desktop.
- Are prefixes still needed?
- Only on very old Android browsers.
- What tasks should I pause when the page is hidden?
- Animations, timers, videos, recurrent requests.
- Can this API be disabled?
- Not in a standard way; some browsers may limit information for privacy.
Conclusion
Although not as flashy as WebGL or WebAudio, the Page Visibility API fulfills an essential role: preventing our pages from consuming unnecessary resources when no one is viewing them.
- In my own projects, it has allowed me to:
- save CPU
- extend battery life on mobile devices
- avoid unnecessary server calls
- improve the user experience
It is simple, stable, and supported practically by all modern browsers.
I agree to receive announcements of interest about this Blog.
The Page Visibility API allows us to know when a web page is being viewed by the user and therefore we can make configurations to avoid the use of unnecessary resources.