Start · Sprachen · JavaScript · Referenz · PerformanceNavigationTiming.notRestoredReasons

PerformanceNavigationTiming.notRestoredReasons

Eigenschaft

Gibt ein <code>NotRestoredReasons</code>-Objekt mit den Gründen zurück, warum das Dokument bei einer Vor-/Zurück-Navigation nicht aus dem Back/Forward-Cache (bfcache) geladen wurde.

seit JavaScript Chrome/Edge 123+ (experimentell, nicht in Firefox Kategorie: webapi

Signatur

PerformanceNavigationTiming.notRestoredReasons

Beschreibung

Die schreibgeschützte Eigenschaft notRestoredReasons des Interfaces PerformanceNavigationTiming zeigt, warum eine Seite nicht aus dem Back/Forward-Cache (bfcache) wiederhergestellt wurde. Wird eine Seite aus dem bfcache geladen, erscheint sie beim Zurück- oder Vorwärts-Navigieren sofort. Wenn der Browser das verhindert, muss er die Seite komplett neu laden. Das kostet Ladezeit und verschlechtert Werte wie LCP und INP.

Der Wert ist ein NotRestoredReasons-Objekt mit diesen Eigenschaften:

  • reasons: Array aus NotRestoredReasonDetails-Objekten. Jedes davon hat eine Eigenschaft reason mit einem Text wie "unload-listener", "response-cache-control-no-store", "websocket" oder "masked".
  • children: Array mit NotRestoredReasons-Objekten für eingebettete <iframe>-Elemente, sonst null.
  • url, src, id, name: Angaben zum Dokument bzw. zum iframe. Beim obersten Dokument sind src, id und name null.

Die Eigenschaft ist nur bei Navigationen vom Typ "back_forward" gefüllt, die nicht aus dem bfcache bedient wurden. Bei allen anderen Navigationen ist der Wert null. Kommt die Seite tatsächlich aus dem bfcache, entsteht gar kein neuer Navigationseintrag. Das erkennst du stattdessen am pageshow-Event mit event.persisted === true. Typischerweise liest du die Eigenschaft im Real User Monitoring (RUM) aus und schickst sie an ein Analyse-Backend.

Rückgabewert

Typ
NotRestoredReasons | null
Beschreibung
Ein NotRestoredReasons-Objekt mit den Gründen, warum der bfcache nicht genutzt wurde, oder null, wenn die Navigation keine Vor-/Zurück-Navigation war.

Beispiele

Gründe beim Laden der Seite auslesen

const [nav] = performance.getEntriesByType('navigation');

if (nav?.type === 'back_forward' && nav.notRestoredReasons) {
  const { url, reasons } = nav.notRestoredReasons;
  console.log('Nicht aus dem bfcache geladen:', url);
  reasons.forEach(({ reason }) => console.log('Grund:', reason));
} else {
  console.log('Keine Gründe vorhanden (keine Vor-/Zurück-Navigation)');
}
Nicht aus dem bfcache geladen: https://example.com/shop Grund: unload-listener

Gründe rekursiv inklusive iframes sammeln

const collectReasons = (node, path = 'top') => {
  if (!node) return [];
  const own = (node.reasons ?? []).map(({ reason }) => ({
    frame: node.src ?? node.url ?? path,
    reason
  }));
  const fromChildren = (node.children ?? []).flatMap((child, i) =>
    collectReasons(child, `${path} > iframe[${i}]`)
  );
  return [...own, ...fromChildren];
};

const [nav] = performance.getEntriesByType('navigation');
console.table(collectReasons(nav?.notRestoredReasons));
┌─────────┬──────────────────────────────────┬──────────────────┐ │ (index) │ frame │ reason │ ├─────────┼──────────────────────────────────┼──────────────────┤ │ 0 │ https://example.com/ │ websocket │ │ 1 │ top > iframe[0] │ masked │ └─────────┴──────────────────────────────────┴──────────────────┘

Per PerformanceObserver an ein RUM-Backend senden

const observer = new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) {
    if (!('notRestoredReasons' in entry) || !entry.notRestoredReasons) continue;

    const payload = JSON.stringify({
      page: location.pathname,
      data: entry.notRestoredReasons.toJSON()
    });
    navigator.sendBeacon('/analytics/bfcache', payload);
  }
});

observer.observe({ type: 'navigation', buffered: true });

// Wichtig · Fallstricke

  • Browser-Unterstützung: Die Eigenschaft gibt es bisher nur in Chromium-Browsern (ab Chrome/Edge 123). Firefox und Safari kennen sie nicht. Prüfe deshalb vorher mit 'notRestoredReasons' in entry, ob sie vorhanden ist. Frühere Chrome-Testversionen hatten eine abweichende Struktur, zum Beispiel ein Feld blocked und Gründe als einfache Texte.
  • Datenschutz: Blockiert ein iframe von einem anderen Ursprung den bfcache, erfährst du den Grund nicht. Stattdessen steht dort "masked". Auch Gründe aus Nutzereinstellungen oder Browser-Interna können als "masked" erscheinen.
  • null ist normal: Bei gewöhnlichen Navigationen ("navigate", "reload") und bei Seiten, die erfolgreich aus dem bfcache kamen, bekommst du keine Gründe. Für den Erfolgsfall reagierst du auf das pageshow-Event mit persisted === true.
  • Häufige Gründe: unload-Handler (nutze stattdessen pagehide), Cache-Control: no-store, offene WebSocket- oder WebRTC-Verbindungen sowie BroadcastChannel-Nachrichten. Die Liste der möglichen Gründe hängt vom Browser ab und kann sich ändern. Werte sie deshalb nicht mit einer festen Liste aus.