Signatur
Beschreibung
Das Interface NotRestoredReasons gehört zur Performance API. Ein Objekt dieses Typs erhältst du über die Eigenschaft PerformanceNavigationTiming.notRestoredReasons. Es gibt an, warum eine Seite bei einer Vor-/Zurück-Navigation nicht aus dem bfcache geladen, sondern komplett neu geladen wurde. Der bfcache sorgt für sofortige Wiederherstellung ohne Neuladen und verbessert dadurch Messwerte wie LCP und INP spürbar. Solche Blockaden zu finden lohnt sich also.
Das Objekt beschreibt den Frame-Baum des Dokuments. Das oberste Objekt steht für das Hauptdokument, und über children erreichst du rekursiv die eingebetteten <iframe>-Elemente. Jeder Knoten hat diese Eigenschaften (alle nur lesbar):
blocked:true, wenn dieser Frame die Nutzung des bfcache verhindert hat, sonstfalse. Bei ursprungsfremden (cross-origin) Frames ist der Wertnull.children: Array vonNotRestoredReasons-Objekten für die direkt eingebetteten Frames, odernull.id/name: Die Attributeidundnamedes<iframe>-Elements, sonstnull.reasons: Array vonNotRestoredReasonDetails-Objekten. Jedes davon hat die Eigenschaftreasonmit einem Grund als Zeichenkette, z. B."unload-listener","websocket","response-cache-control-no-store"oder"masked".src: Dassrc-Attribut des Frames bzw.null.url: Die URL des Dokuments im Frame. Bei ursprungsfremden Frames kann der Wertnullsein.
Die Methode toJSON() liefert eine JSON-taugliche Darstellung des ganzen Baums. Damit kannst du die Gründe direkt an einen Analyse-Endpunkt schicken. Typischer Einsatz ist das Real-User-Monitoring (RUM): Du sammelst im Produktivbetrieb, welche Skripte, Header oder Drittanbieter-iframes den bfcache blockieren.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $toJSON() | method | Einzige Methode des Interfaces, ohne Parameter. Gibt ein einfaches Objekt mit allen Eigenschaften zurück, einschließlich der verschachtelten children. |
Rückgabewert
PerformanceNavigationTiming.notRestoredReasons liefert ein NotRestoredReasons-Objekt, wenn die Navigation eine Vor-/Zurück-Navigation war (type === "back_forward") und die Seite nicht aus dem bfcache kam. Bei anderen Navigationsarten ist der Wert null.Beispiele
Gründe der aktuellen Navigation auslesen
const [nav] = performance.getEntriesByType('navigation');
if (nav?.notRestoredReasons) {
const nrr = nav.notRestoredReasons;
console.log('Blockiert:', nrr.blocked);
console.log('Gründe:', nrr.reasons.map((r) => r.reason));
} else {
console.log('Keine bfcache-Informationen (keine Vor-/Zurück-Navigation oder API nicht unterstützt).');
}
Frame-Baum rekursiv durchlaufen
const collectBlockers = (node, path = 'top') => {
const result = [];
if (!node) return result;
const reasons = (node.reasons ?? []).map((r) => r.reason);
if (node.blocked || reasons.length) {
result.push({ path, url: node.url, src: node.src, reasons });
}
(node.children ?? []).forEach((child, i) => {
const label = child.id || child.name || `iframe[${i}]`;
result.push(...collectBlockers(child, `${path} > ${label}`));
});
return result;
};
const [nav] = performance.getEntriesByType('navigation');
console.table(collectBlockers(nav?.notRestoredReasons));
Gründe per PerformanceObserver an das Monitoring senden
if ('PerformanceObserver' in window) {
const observer = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
if (entry.type !== 'back_forward' || !entry.notRestoredReasons) continue;
const payload = JSON.stringify({
page: location.pathname,
notRestoredReasons: entry.notRestoredReasons.toJSON(),
});
navigator.sendBeacon('/analytics/bfcache', payload);
}
});
observer.observe({ type: 'navigation', buffered: true });
}
// Wichtig · Fallstricke
- Kompatibilität: Die API ist experimentell und bisher nur in Chromium-Browsern verfügbar (Chrome/Edge ab 123). Firefox und Safari unterstützen sie nicht. Prüfe deshalb immer mit
?.oder'notRestoredReasons' in entry, bevor du darauf zugreifst. - Kein Eintrag bei Erfolg: Wird eine Seite erfolgreich aus dem bfcache wiederhergestellt, entsteht kein neuer Navigations-Eintrag. Das erkennst du stattdessen am Event
pageshowmitevent.persisted === true. - Datenschutz bei cross-origin-iframes: Blockiert ein ursprungsfremder Frame den bfcache, werden seine genauen Gründe nicht offengelegt. Im obersten Dokument erscheint dann
"masked", undblockedbzw.reasonsdes Frames sindnull. Um Nutzerdaten zu schützen, kann"masked"auch zusätzlich zu anderen Gründen vorkommen. - Gründe können sich ändern: Die Liste möglicher Werte in
reasonist nicht abschließend und kann sich zwischen Browserversionen ändern. Werte sie deshalb flexibel aus und nicht als festen Satz von Konstanten. - Häufige Blocker sind
unload-Listener, der HeaderCache-Control: no-store, offene WebSocket- oder WebRTC-Verbindungen und nicht beendete IndexedDB-Transaktionen. Nimm stattunloadbesserpagehide.