Signatur
Beschreibung
VisibilityStateEntry ist ein Eintrag der Performance-Zeitleiste mit dem entryType "visibility-state". Der Browser legt einen solchen Eintrag bei jedem Wechsel des Sichtbarkeitszustands eines Dokuments an, zum Beispiel wenn der Tab gewechselt, das Fenster minimiert oder die Seite im Hintergrund geladen wird. Außerdem gibt es einen ersten Eintrag bei startTime 0, der den Anfangszustand festhält.
Die wichtigsten Eigenschaften sind name (der neue Zustand, also "visible" oder "hidden") und startTime (der Zeitpunkt des Wechsels als DOMHighResTimeStamp relativ zu performance.timeOrigin). duration ist immer 0, weil der Wechsel als einzelner Zeitpunkt erfasst wird.
Nützlich ist das Interface vor allem für Real User Monitoring (RUM): Metriken wie LCP oder FCP sind verfälscht, wenn die Seite beim Laden im Hintergrund war. Mit VisibilityStateEntry lässt sich im Nachhinein prüfen, ob und wann die Seite versteckt war. Man muss dafür nicht selbst früh einen visibilitychange-Listener registrieren.
Ausgelesen werden die Einträge mit einem PerformanceObserver (Typ "visibility-state", am besten mit buffered: true) oder mit performance.getEntriesByType("visibility-state"). Einen eigenen Konstruktor gibt es nicht, die Einträge erzeugt ausschließlich der Browser.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $name Pflicht | string | Eigenschaft (schreibgeschützt): der neue Sichtbarkeitszustand, "visible" oder "hidden". |
|
| $entryType Pflicht | string | "visibility-state" | Eigenschaft (schreibgeschützt): immer "visibility-state". |
| $startTime Pflicht | DOMHighResTimeStamp | Eigenschaft (schreibgeschützt): Zeitpunkt des Zustandswechsels in Millisekunden seit performance.timeOrigin. Der Anfangszustand hat 0. |
|
| $duration Pflicht | number | 0 | Eigenschaft (schreibgeschützt): immer 0. |
| $toJSON() | function | Geerbte Methode: gibt eine JSON-Darstellung des Eintrags zurück, praktisch zum Versenden an einen Analytics-Endpunkt. |
Rückgabewert
PerformanceObserver-Callbacks oder performance.getEntriesByType("visibility-state"). Es gibt keinen öffentlichen Konstruktor.Beispiele
Sichtbarkeitswechsel mit PerformanceObserver beobachten
if (PerformanceObserver.supportedEntryTypes?.includes('visibility-state')) {
const observer = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
console.log(`${entry.name} ab ${entry.startTime.toFixed(0)} ms`);
}
});
// buffered: true liefert auch die Einträge, die vor der Registrierung entstanden sind
observer.observe({ type: 'visibility-state', buffered: true });
} else {
console.log('visibility-state wird nicht unterstützt');
}
Prüfen, ob die Seite vor dem LCP versteckt war
const wasHiddenBefore = (timestamp) =>
performance
.getEntriesByType('visibility-state')
.some((e) => e.name === 'hidden' && e.startTime < timestamp);
new PerformanceObserver((list) => {
const entries = list.getEntries();
const lcp = entries[entries.length - 1];
if (wasHiddenBefore(lcp.startTime)) {
console.log('LCP verworfen: Seite war zwischendurch im Hintergrund');
} else {
console.log('LCP:', Math.round(lcp.startTime), 'ms');
}
}).observe({ type: 'largest-contentful-paint', buffered: true });
Gesamte Sichtbarkeitsdauer berechnen und senden
const visibleTime = () => {
const entries = performance.getEntriesByType('visibility-state');
let total = 0;
let visibleSince = null;
for (const e of entries) {
if (e.name === 'visible' && visibleSince === null) visibleSince = e.startTime;
if (e.name === 'hidden' && visibleSince !== null) {
total += e.startTime - visibleSince;
visibleSince = null;
}
}
if (visibleSince !== null) total += performance.now() - visibleSince;
return Math.round(total);
};
document.addEventListener('visibilitychange', () => {
if (document.visibilityState === 'hidden') {
navigator.sendBeacon('/analytics', JSON.stringify({ visibleMs: visibleTime() }));
}
});
// Wichtig · Fallstricke
Experimentell: Derzeit unterstützen nur Chromium-Browser das Interface (Chrome und Edge ab 115). Firefox und Safari unterstützen es nicht. Prüfen Sie die Unterstützung deshalb immer vorher mit PerformanceObserver.supportedEntryTypes.includes('visibility-state'). Als Rückfallebene können Sie document.visibilityState und das Ereignis visibilitychange verwenden.
- Ohne
buffered: truefehlen dem Observer alle Einträge, die vor seiner Registrierung entstanden sind, einschließlich des Anfangszustands beistartTime0. durationist immer0. Wie lange ein Zustand gedauert hat, müssen Sie selbst aus der Differenz aufeinanderfolgenderstartTime-Werte berechnen.- Wenn die Seite aus dem Back/Forward-Cache (bfcache) wiederhergestellt wird, beginnt keine neue Zeitleiste. Für solche Fälle sollten Sie zusätzlich auf
pageshowmitevent.persistedachten. - Der Zustand
"prerender"aus der Page Visibility API erscheint hier nicht als Eintrag.