Start · Sprachen · JavaScript · Referenz · NotRestoredReasons

NotRestoredReasons

Schnittstelle

Enthält die Gründe, warum ein Dokument und seine Frames bei einer Vor-/Zurück-Navigation nicht aus dem back/forward Cache (bfcache) wiederhergestellt wurden.

seit JavaScript Experimentell: Chrome/Edge 123+ (nur Chromium) Kategorie: webapi

Signatur

interface NotRestoredReasons

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, sonst false. Bei ursprungsfremden (cross-origin) Frames ist der Wert null.
  • children: Array von NotRestoredReasons-Objekten für die direkt eingebetteten Frames, oder null.
  • id / name: Die Attribute id und name des <iframe>-Elements, sonst null.
  • reasons: Array von NotRestoredReasonDetails-Objekten. Jedes davon hat die Eigenschaft reason mit einem Grund als Zeichenkette, z. B. "unload-listener", "websocket", "response-cache-control-no-store" oder "masked".
  • src: Das src-Attribut des Frames bzw. null.
  • url: Die URL des Dokuments im Frame. Bei ursprungsfremden Frames kann der Wert null sein.

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

Typ
NotRestoredReasons | null
Beschreibung
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).');
}
Blockiert: true Gründe: ["unload-listener", "websocket"]

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));
┌─────────┬──────────────────┬───────────────────────────┬──────┬─────────────────────┐ │ (index) │ path │ url │ src │ reasons │ │ 0 │ 'top' │ 'https://example.com/' │ null │ ['masked'] │ │ 1 │ 'top > werbung' │ null │ '…' │ [] │ └─────────┴──────────────────┴───────────────────────────┴──────┴─────────────────────┘

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 pageshow mit event.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", und blocked bzw. reasons des Frames sind null. 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 reason ist 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 Header Cache-Control: no-store, offene WebSocket- oder WebRTC-Verbindungen und nicht beendete IndexedDB-Transaktionen. Nimm statt unload besser pagehide.