This feature is not Baseline because it does not work in some of the most widely-used browsers.
Experimental: This is an experimental technology
Check the Browser compatibility table carefully before using this in production.
The VisibilityStateEntry interface provides timings of page visibility state changes, i.e., when a tab changes from the foreground to the background or vice versa.
This can be used to pinpoint visibility changes on the performance timeline, and cross-reference them against other performance entries such as "first-contentful-paint" (see PerformancePaintTiming).
There are two key visibility state change times that this API reports on:
visible: The time when the page becomes visible (i.e., when its tab moves into the foreground).hidden: The time when the pages become hidden (i.e., when its tab moves into the background).The performance timeline will always have a "visibility-state" entry with a startTime of 0 and a name representing the initial page visibility state.
Note: Like other Performance APIs, this API extends PerformanceEntry.
This interface has no properties but it extends the properties of PerformanceEntry by qualifying and constraining them as follows:
PerformanceEntry.entryType Experimental
Returns "visibility-state".
PerformanceEntry.name Experimental
Returns either "visible" or "hidden".
PerformanceEntry.startTime Experimental
Returns the timestamp when the visibility state change occurred.
PerformanceEntry.duration Experimental
Returns 0.
This interface has no methods.
The following function could be used to log a table of all "visibility-state" performance entries to the console:
function getVisibilityStateEntries() {
const visibilityStateEntries =
performance.getEntriesByType("visibility-state");
console.table(visibilityStateEntries);
}
The below function gets a reference to all "visibility-state" entries and the "first-contentful-paint" entry, then uses Array.some() to test whether any of the "hidden" visibility entries occurred before the first contentful paint:
function wasHiddenBeforeFirstContentfulPaint() {
const fcpEntry = performance.getEntriesByName("first-contentful-paint")[0];
const visibilityStateEntries =
performance.getEntriesByType("visibility-state");
return visibilityStateEntries.some(
(e) => e.startTime < fcpEntry.startTime && e.name === "hidden",
);
}
| Specification |
|---|
| HTML> # the-visibilitystateentry-interface> |
| Desktop | Mobile | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android | WebView on iOS | |
VisibilityStateEntry |
115 | 115 | No | 101 | No | 115 | No | 77 | No | 23.0 | 115 | No |
duration |
115 | 115 | No | 101 | No | 115 | No | 77 | No | 23.0 | 115 | No |
entryType |
115 | 115 | No | 101 | No | 115 | No | 77 | No | 23.0 | 115 | No |
name |
115 | 115 | No | 101 | No | 115 | No | 77 | No | 23.0 | 115 | No |
startTime |
115 | 115 | No | 101 | No | 115 | No | 77 | No | 23.0 | 115 | No |
© 2005–2025 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/API/VisibilityStateEntry