Signatur
Beschreibung
Die schreibgeschützte Eigenschaft reasons der Schnittstelle NotRestoredReasons enthält ein Array von NotRestoredReasonDetails-Objekten. Jedes Objekt steht für einen Grund, warum der Browser die Seite bei einer Vor- oder Zurück-Navigation nicht aus dem Back/Forward-Cache (bfcache) laden konnte. Den eigentlichen Grund als Zeichenkette liefert die Eigenschaft reason des jeweiligen Detail-Objekts, z. B. "unload-listener", "websocket", "broadcastchannel-message", "lock" oder "response-cache-control-no-store".
Das NotRestoredReasons-Objekt bekommt man über PerformanceNavigationTiming.notRestoredReasons, also über performance.getEntriesByType("navigation")[0]. Es beschreibt das Dokument im Hauptframe. Eingebettete Frames tauchen im Array children auf, und jeder davon hat wiederum ein eigenes reasons-Array.
Gedacht ist die Eigenschaft vor allem für Real User Monitoring. Man sammelt die Gründe im Feld und schickt sie an ein Analyse-Backend. So findet man heraus, welche Code-Teile (z. B. unload-Handler oder offene WebSocket-Verbindungen) den bfcache verhindern und damit die Rücknavigation langsamer machen.
Rückgabewert
NotRestoredReasonDetails-Objekten, jedes mit der Eigenschaft reason (string). Ist es leer, hat dieses Dokument selbst nichts blockiert. Die Blockade kann dann aus einem Unterframe kommen (siehe children). Bei ursprungsübergreifenden (cross-origin) iframes ist der Wert null, damit keine Informationen nach außen gelangen.Beispiele
Gründe für die verpasste bfcache-Wiederherstellung ausgeben
const [nav] = performance.getEntriesByType('navigation');
if (nav?.notRestoredReasons) {
const { reasons, blocked } = nav.notRestoredReasons;
console.log('Blockiert:', blocked);
for (const detail of reasons ?? []) {
console.log('Grund:', detail.reason);
}
} else {
console.log('Keine Daten (keine Zurück-Navigation oder API nicht unterstützt)');
}
Gründe rekursiv inklusive iframes sammeln
const collectReasons = (nrr, path = 'top') => {
if (!nrr) return [];
const own = (nrr.reasons ?? []).map((d) => ({
frame: nrr.src || nrr.url || path,
reason: d.reason,
}));
const fromChildren = (nrr.children ?? []).flatMap((child, i) =>
collectReasons(child, `${path} > iframe[${i}]`)
);
return [...own, ...fromChildren];
};
const [nav] = performance.getEntriesByType('navigation');
console.table(collectReasons(nav?.notRestoredReasons));
Gründe per sendBeacon an das Monitoring schicken
const reportBfcacheReasons = () => {
if (!('PerformanceNavigationTiming' in window)) return;
const [nav] = performance.getEntriesByType('navigation');
if (nav?.type !== 'back_forward' || !nav.notRestoredReasons) return;
const reasons = (nav.notRestoredReasons.reasons ?? []).map((d) => d.reason);
navigator.sendBeacon('/analytics/bfcache', JSON.stringify({
url: location.href,
reasons,
}));
};
reportBfcacheReasons();
// Wichtig · Fallstricke
- Browser-Unterstützung: Die API ist experimentell und gibt es nur in Chromium-Browsern (Chrome/Edge ab 123). Deshalb vorher auf Existenz prüfen, z. B. mit
nav?.notRestoredReasons. notRestoredReasonsist nur bei Zurück- oder Vor-Navigationen gefüllt (type === "back_forward"), bei denen der bfcache nicht gegriffen hat. Wird die Seite tatsächlich aus dem bfcache geladen, entsteht kein neuer Navigationseintrag. Das erkennt man stattdessen anpageshowmitevent.persisted === true.- Bei cross-origin iframes ist
reasonsaus Datenschutzgründennull. Blockiert so ein Frame, erscheint im übergeordneten Dokument nur der Sammelgrund"masked". - Ein leeres Array heißt nicht, dass die Seite restaurierbar war. Die Ursache kann in einem Unterframe liegen, deshalb auch
childrenauswerten. - Die Grund-Zeichenketten sind nicht abschließend genormt und können sich zwischen Browserversionen ändern. Beim Auswerten tolerant sein und keine feste Aufzählung voraussetzen.