Back-Forward-Cache

Der Back-Forward-Cache (oder bfcache) ist eine Browseroptimierung, die eine sofortige und vorwärtsgerichtete Navigation ermöglicht. Dadurch wird das Surfen für Nutzer erheblich verbessert, insbesondere für langsamere Netzwerke oder Geräte.

Als Webentwickler müssen Sie wissen, wie Sie Ihre Seiten für den bfcache optimieren, damit Ihre Nutzer davon profitieren können.

Browserkompatibilität

Alle gängigen Browser enthalten einen bfcache, einschließlich Chrome ab Version 96, Firefox und Safari.

bfcache-Grundlagen

Mit dem Back-Forward-Cache (bfcache) verschieben wir das Löschen und pausieren die JavaScript-Ausführung, anstatt eine Seite zu zerstören, wenn der Nutzer die Seite verlässt. Wenn der Nutzer bald zurückwechselt, wird die Seite wieder sichtbar gemacht und die Ausführung von JavaScript wird fortgesetzt. Das führt zu einer nahezu sofortigen Seitennavigation für den Nutzer.

Wie oft haben Sie eine Website besucht und auf einen Link geklickt, um eine andere Seite aufzurufen, nur um dann festzustellen, dass Sie nicht das gesuchte gefunden haben, und auf die Schaltfläche „Zurück“ geklickt? In diesem Moment kann der bfcache einen großen Unterschied bei der Geschwindigkeit des Ladens der vorherigen Seite ausmachen:

Ohne aktiviertem bfcache Es wird eine neue Anfrage gestartet, um die vorherige Seite zu laden. Je nachdem, wie gut diese Seite für wiederholte Besuche optimiert wurde, muss der Browser möglicherweise einige oder alle gerade heruntergeladenen Ressourcen noch einmal herunterladen, parsen und ausführen.
Mit aktiviertem bfcache Das Laden der vorherigen Seite ist praktisch sofort, da die gesamte Seite aus dem Arbeitsspeicher wiederhergestellt werden kann, ohne dass das Netzwerk überhaupt kontaktiert werden muss.

In diesem Video sehen Sie, wie der bfcache die Navigation beschleunigen kann:

Mit bfcache werden Seiten beim Zurück- und Vorwärtsnavigationen viel schneller geladen.

Im Video ist das Beispiel mit bfcache deutlich schneller als das Beispiel ohne bfcache.

bfcache beschleunigt nicht nur die Navigation, sondern verringert auch die Datennutzung, da Ressourcen nicht noch einmal heruntergeladen werden müssen.

Chrome-Nutzungsdaten zeigen, dass 1 von 10 Navigationen auf dem Computer und 1 von 5 auf Mobilgeräten entweder zurück oder vorwärts ist. Wenn der bfcache aktiviert ist, können Browser die Datenübertragung und die Ladezeit für Milliarden von Webseiten jeden Tag eliminieren.

Funktionsweise des Cache

Der von bfcache verwendete "Cache" unterscheidet sich vom HTTP-Cache, der eine eigene Rolle bei der Beschleunigung wiederholter Navigationen spielt. "bfcache" ist ein Snapshot der gesamten Seite im Arbeitsspeicher, einschließlich des JavaScript-Heaps, während der HTTP-Cache nur die Antworten für zuvor gestellte Anfragen enthält. Da es sehr selten ist, dass alle Anforderungen, die zum Laden einer Seite erforderlich sind, aus dem HTTP-Cache ausgeführt werden können, sind wiederholte Besuche mit bfcache-Wiederherstellungen immer schneller als selbst die am besten optimierten Navigationen ohne bfcache.

Das Einfrieren einer Seite, um sie später möglicherweise wieder zu aktivieren, ist insofern etwas kompliziert, als dass der in Bearbeitung befindliche Code am besten erhalten werden sollte. Wie werden beispielsweise setTimeout()-Aufrufe verarbeitet, bei denen das Zeitlimit erreicht wird, während sich die Seite im bfCache befindet?

Die Antwort ist, dass Browser ausstehende Timer oder ungelöste Promis für Seiten im bfcache anhalten, einschließlich fast aller ausstehenden Aufgaben in den JavaScript-Aufgabenwarteschlangen, und Verarbeitungsaufgaben fortsetzen, wenn die Seite aus dem bfcache wiederhergestellt wird.

In einigen Fällen, z. B. bei Zeitüberschreitungen und Versprechen, ist das Risiko relativ gering. In anderen Fällen kann es jedoch zu verwirrendem oder unerwartetem Verhalten führen. Wenn der Browser beispielsweise eine Aufgabe pausiert, die im Rahmen einer IndexedDB-Transaktion erforderlich ist, kann sich das auf andere geöffnete Tabs im selben Ursprung auswirken, da auf dieselben IndexedDB-Datenbanken gleichzeitig über mehrere Tabs zugegriffen werden kann. Daher versuchen Browser in der Regel nicht, Seiten mitten in einer IndexedDB-Transaktion oder bei der Verwendung von APIs zu cachen, die sich auf andere Seiten auswirken könnten.

Weitere Informationen dazu, wie sich die Verwendung verschiedener APIs auf die Eignung einer Seite für den bfcache auswirkt, finden Sie unter Seiten für den bfcache optimieren.

bfcache und iFrames

Wenn eine Seite eingebettete iFrames enthält, können die iFrames selbst nicht für den bfcache verwendet werden. Wenn Sie beispielsweise innerhalb eines Iframes zu einer anderen Seite wechseln und dann zurückgehen, wechselt der Browser innerhalb des Iframes zurück, nicht im Hauptframe. Bei der Rückwärtsnavigation innerhalb des Iframes wird jedoch nicht der bfcache verwendet.

Die Verwendung des bfcache kann auch für den Hauptframe blockiert werden, wenn ein eingebetteter Iframe APIs verwendet, die dies blockieren. Du kannst dies mithilfe der Berechtigungsrichtlinie im Hauptframe oder der Verwendung von sandbox-Attributen vermeiden.

bfcache und Single-Page-Anwendungen (SPA)

Da bfcache mit browsergestützten Navigationen funktioniert, ist er nicht für „weiche Navigationen“ in einer Single-Page-Anwendung (SPA) geeignet. bfcache kann jedoch hilfreich sein, wenn Sie zu einer SPA zurückkehren, anstatt diese App von vornherein vollständig neu zu initialisieren.

APIs zum Beobachten des bfcache

Auch wenn die BFCache-Optimierung von Browsern automatisch erfolgt, ist es für Entwickler wichtig zu wissen, wann sie stattfindet, damit sie ihre Seiten entsprechend optimieren und alle Messwerte oder Leistungsmessungen anpassen können.

Die wichtigsten Ereignisse, die zum Beobachten von bfcache verwendet werden, sind die Seitenübergangsereignisse pageshow und pagehide, die von den meisten Browsern unterstützt werden.

Die neueren Ereignisse zum Seitenlebenszyklus – freeze und resume – werden auch gesendet, wenn Seiten den bfcache betreten oder verlassen, sowie in einigen anderen Situationen, z. B. wenn ein Hintergrundtab eingefroren wird, um die CPU-Auslastung zu minimieren. Diese Ereignisse werden nur in Chromium-basierten Browsern unterstützt.

Beobachten, wenn eine Seite aus bfcache wiederhergestellt wird

Das Ereignis pageshow wird direkt nach dem Ereignis load ausgelöst, wenn die Seite zum ersten Mal geladen wird, und jedes Mal, wenn die Seite aus dem bfcache wiederhergestellt wird. Das Ereignis pageshow hat die Property persisted. Diese hat den Wert true, wenn die Seite aus dem bfcache wiederhergestellt wurde, andernfalls false. Mit der Property persisted können Sie normale Seitenladevorgänge von BFCache-Wiederherstellungen unterscheiden. Beispiel:

window.addEventListener('pageshow', (event) => {
  if (event.persisted) {
    console.log('This page was restored from the bfcache.');
  } else {
    console.log('This page was loaded normally.');
  }
});

In Browsern, die die Page Lifecycle API unterstützen, wird das Ereignis resume ausgelöst, wenn Seiten aus dem bfcache wiederhergestellt werden (unmittelbar vor dem Ereignis pageshow) und wenn ein Nutzer einen eingefrorenen Hintergrundtab noch einmal aufruft. Wenn Sie den Status einer Seite aktualisieren möchten, nachdem sie eingefroren wurde (einschließlich Seiten im bfcache), können Sie das Ereignis resume verwenden. Wenn Sie jedoch die bfcache-Trefferrate Ihrer Website messen möchten, müssen Sie das Ereignis pageshow verwenden. In einigen Fällen müssen Sie möglicherweise beide verwenden.

Weitere Informationen zu Best Practices für die bfcache-Messung finden Sie unter Auswirkungen von bfcache auf Analysen und Leistungsmessungen.

Beobachten, wann eine Seite in den bfcache aufgenommen wird

Das pagehide-Ereignis wird entweder ausgelöst, wenn eine Seite entladen wird oder wenn der Browser versucht, sie in den bfcache zu speichern.

Das Ereignis pagehide hat auch eine persisted-Eigenschaft. Wenn der Wert false ist, wird die Seite nicht in den bfcache aufgenommen. Allerdings ist persisted true keine Garantie dafür, dass eine Seite im Cache gespeichert wird. Das bedeutet, dass der Browser künftig versucht, die Seite im Cache zu speichern. Es gibt jedoch möglicherweise andere Faktoren, die das Speichern im Cache erschweren.

window.addEventListener('pagehide', (event) => {
  if (event.persisted) {
    console.log('This page *might* be entering the bfcache.');
  } else {
    console.log('This page will unload normally and be discarded.');
  }
});

Ähnlich wird das Ereignis freeze unmittelbar nach dem Ereignis pagehide ausgelöst, wenn persisted true ist. Das bedeutet jedoch nur, dass der Browser beabsichtigt, die Seite im Cache zu speichern. Es kann jedoch aus verschiedenen Gründen, die später erläutert werden, sein, dass sie trotzdem verworfen werden muss.

Seiten für bfcache optimieren

Nicht alle Seiten werden im bfcache gespeichert. Selbst wenn eine Seite dort gespeichert wird, bleibt sie nicht unbegrenzt dort. Es ist wichtig, dass die Entwickler verstehen, warum Seiten für bfcache infrage kommen (und nicht infrage kommen), um ihre Cache-Trefferraten zu maximieren.

In den folgenden Abschnitten werden Best Practices beschrieben, mit denen Sie die Wahrscheinlichkeit erhöhen können, dass der Browser Ihre Seiten im Cache speichert.

Verwenden Sie das Ereignis unload nie.

Die wichtigste Maßnahme zur Optimierung für bfcache in allen Browsern besteht darin, das Ereignis unload nie zu verwenden. Überhaupt nicht!

Das Ereignis unload ist für Browser problematisch, da es älter als bfcache ist und viele Seiten im Internet davon ausgehen, dass eine Seite nach dem Auslösen des Ereignisses unload nicht mehr existiert. Das stellt eine Herausforderung dar, da viele dieser Seiten auch unter der Annahme erstellt wurden, dass das unload-Ereignis jedes Mal ausgelöst wird, wenn ein Nutzer die Seite verlässt. Das ist jedoch nicht mehr der Fall (und schon seit einiger Zeit nicht mehr).

Browser stehen also vor einem Dilemma: Sie müssen sich zwischen einer Option entscheiden, die die Nutzerfreundlichkeit verbessern kann, aber auch das Risiko birgt, dass die Seite nicht richtig angezeigt wird.

Auf dem Computer werden Seiten in Chrome und Firefox nicht für den bfcache zugelassen, wenn ein unload-Listener hinzugefügt wird. Das ist zwar weniger riskant, schließt aber auch viele Seiten aus. Safari versucht, einige Seiten mit einem unload-Ereignis-Listener im Cache zu speichern. Um potenzielle Fehler zu vermeiden, wird das unload-Ereignis jedoch nicht ausgeführt, wenn ein Nutzer die Seite verlässt. Das Ereignis ist daher sehr unzuverlässig.

Auf Mobilgeräten versuchen Chrome und Safari, Seiten mit einem unload-Event-Listener im Cache zu speichern, da das Fehlerrisiko geringer ist, da das unload-Ereignis auf Mobilgeräten immer extrem unzuverlässig war. Firefox behandelt Seiten, auf denen unload verwendet wird, als nicht für den bfcache geeignet, mit Ausnahme von iOS. Dort müssen alle Browser die WebKit-Rendering-Engine verwenden, sodass sich Firefox wie Safari verhält.

Verwenden Sie stattdessen das Ereignis pagehide. Das pagehide-Ereignis wird immer ausgelöst, wenn das unload-Ereignis ausgelöst wird. Es wird auch ausgelöst, wenn eine Seite in den bfcache abgelegt wird.

Lighthouse bietet sogar eine no-unload-listeners-Prüfung, bei der Entwickler gewarnt werden, wenn JavaScript auf ihren Seiten (einschließlich JavaScript von Drittanbieterbibliotheken) einen unload-Ereignis-Listener hinzufügt.

Aufgrund seiner Unzuverlässigkeit und der Leistungseinbußen für den bfcache wird das unload-Ereignis in Chrome eingestellt.

Mithilfe der Berechtigungsrichtlinie verhindern, dass auf einer Seite Unload-Handler verwendet werden

Inhaber von Websites, die keine unload-Ereignis-Handler verwenden, können mithilfe einer Berechtigungsrichtlinie dafür sorgen, dass diese nicht hinzugefügt werden.

Permission-Policy: unload=()

Außerdem wird dadurch verhindert, dass Drittanbieter oder Erweiterungen die Website verlangsamen, indem sie Unload-Handler hinzufügen, wodurch die Website nicht mehr für den bfcache verwendet werden kann.

Nur beforeunload Listener bedingt hinzufügen

Das Ereignis beforeunload führt nicht dazu, dass Ihre Seiten in modernen Browsern nicht mehr für den bfcache infrage kommen. Das war früher aber der Fall und das Ereignis ist immer noch unzuverlässig. Verwenden Sie es daher nur, wenn es unbedingt erforderlich ist.

Im Gegensatz zum unload-Ereignis gibt es jedoch legitime Anwendungsfälle für beforeunload. Beispielsweise, wenn Sie den Nutzer warnen möchten, dass seine nicht gespeicherten Änderungen verloren gehen, wenn er die Seite verlässt. In diesem Fall empfehlen wir, beforeunload-Listener nur hinzuzufügen, wenn ein Nutzer nicht gespeicherte Änderungen hat, und sie dann sofort wieder zu entfernen, nachdem die nicht gespeicherten Änderungen gespeichert wurden.

Don'ts
window.addEventListener('beforeunload', (event) => {
  if (pageHasUnsavedChanges()) {
    event.preventDefault();
    return event.returnValue = 'Are you sure you want to exit?';
  }
});
Mit diesem Code wird ein beforeunload-Listener ohne Bedingungen hinzugefügt.
Do
function beforeUnloadListener(event) {
  event.preventDefault();
  return event.returnValue = 'Are you sure you want to exit?';
};

// A function that invokes a callback when the page has unsaved changes.
onPageHasUnsavedChanges(() => {
  window.addEventListener('beforeunload', beforeUnloadListener);
});

// A function that invokes a callback when the page's unsaved changes are resolved.
onAllChangesSaved(() => {
  window.removeEventListener('beforeunload', beforeUnloadListener);
});
Mit diesem Code wird der beforeunload-Listener nur hinzugefügt, wenn er benötigt wird, und entfernt, wenn er nicht benötigt wird.

Nutzung von Cache-Control: no-store minimieren

Cache-Control: no-store ist ein HTTP-Header, den Webserver für Antworten festlegen können, der den Browser anweist, die Antwort nicht in einem HTTP-Cache zu speichern. Sie wird für Ressourcen verwendet, die vertrauliche Nutzerinformationen enthalten, z. B. Seiten, die eine Anmeldung erfordern.

Obwohl bfcache kein HTTP-Cache ist, ist es in der Vergangenheit nicht möglich, dass Seiten, die Cache-Control: no-store verwenden, für bfcache infrage kommen, wenn Cache-Control: no-store für die Seitenressource selbst (und nicht für eine Unterressource) festgelegt wurde. Wir arbeiten daran, dieses Verhalten für Chrome datenschutzfreundlich zu ändern.

Da Cache-Control: no-store die Eignung einer Seite für den bfcache einschränkt, sollte es nur auf Seiten festgelegt werden, die vertrauliche Informationen enthalten, und auf denen irgendeine Art von Caching nie angebracht ist.

Verwenden Sie Cache-Control: no-cache oder Cache-Control: max-age=0 für Seiten, auf denen immer aktuelle Inhalte gesendet werden müssen und die keine vertraulichen Informationen enthalten. Diese Anweisungen weisen den Browser an, die Inhalte vor der Auslieferung noch einmal zu validieren. Sie haben keinen Einfluss darauf, ob eine Seite für den bfcache infrage kommt.

Wenn eine Seite aus dem bfcache wiederhergestellt wird, wird sie aus dem Arbeitsspeicher und nicht aus dem HTTP-Cache wiederhergestellt. Daher werden Anweisungen wie Cache-Control: no-cache oder Cache-Control: max-age=0 nicht berücksichtigt und es erfolgt keine erneute Validierung, bevor die Inhalte dem Nutzer angezeigt werden.

Dies ist jedoch wahrscheinlich immer noch eine bessere Nutzererfahrung, da die Wiederherstellung des bfcaches sofort erfolgt und da Seiten nicht sehr lange im bfcache bleiben, ist es unwahrscheinlich, dass die Inhalte veraltet sind. Wenn sich Ihre Inhalte jedoch stündlich ändern, können Sie alle Updates mit dem Ereignis pageshow abrufen, wie im nächsten Abschnitt beschrieben.

Veraltete oder sensible Daten nach der Wiederherstellung des bfcache aktualisieren

Wenn Ihre Website den Nutzerstatus speichert, insbesondere vertrauliche Nutzerdaten, müssen diese Daten aktualisiert oder gelöscht werden, nachdem eine Seite aus dem bfcache wiederhergestellt wurde.

Wenn ein Nutzer beispielsweise eine Zahlungsseite aufruft und dann seinen Einkaufswagen aktualisiert, werden beim Zurückgehen möglicherweise veraltete Informationen angezeigt, wenn eine veraltete Seite aus dem bfcache wiederhergestellt wird.

Ein weiteres, kritischeres Beispiel ist, wenn sich ein Nutzer auf einem öffentlichen Computer von einer Website abmeldet und der nächste Nutzer auf die Schaltfläche „Zurück“ klickt. Dies kann dazu führen, dass private Daten offengelegt werden, die der Nutzer davon ausging, dass sie bei der Abmeldung gelöscht wurden.

Um solche Situationen zu vermeiden, sollten Sie die Seite immer nach einem pageshow-Ereignis aktualisieren, wenn event.persisted true ist:

window.addEventListener('pageshow', (event) => {
  if (event.persisted) {
    // Do any checks and updates to the page
  }
});

Idealerweise aktualisieren Sie die Inhalte vor Ort. Bei einigen Änderungen sollten Sie jedoch ein vollständiges Neuladen erzwingen. Im folgenden Code wird im Ereignis pageshow nach einem websitespezifischen Cookie gesucht und die Seite neu geladen, falls das Cookie nicht gefunden wird:

window.addEventListener('pageshow', (event) => {
  if (event.persisted && !document.cookie.match(/my-cookie)) {
    // Force a reload if the user has logged out.
    location.reload();
  }
});

Ein Neuladen hat den Vorteil, dass der Verlauf erhalten bleibt (um die Navigation nach vorne zu ermöglichen). In einigen Fällen ist eine Weiterleitung jedoch möglicherweise besser geeignet.

Anzeigen und bfcache wiederherstellen

Es kann verlockend sein, den bfcache zu vermeiden, um bei jedem Zurück-/Vorwärts-Navigationsvorgang eine neue Gruppe von Anzeigen auszuliefern. Neben den Leistungseinbußen ist jedoch fraglich, ob ein solches Verhalten zu einem besseren Anzeigen-Engagement führt. Nutzer haben möglicherweise eine Anzeige gesehen, auf die sie zurückgehen und klicken wollten. Da die Anzeige jedoch nicht aus dem bfcache wiederhergestellt, sondern neu geladen wurde, ist das nicht möglich. Es ist wichtig, dieses Szenario zu testen, idealerweise mit einem A/B-Test, bevor Sie Annahmen treffen.

Wenn Sie Anzeigen bei der Wiederherstellung des bfcache aktualisieren möchten, können Sie dies tun, ohne die Seitenleistung zu beeinträchtigen, indem Sie nur die Anzeigen beim Ereignis pageshow aktualisieren, wenn event.persisted = true ist. Erkundige dich bei deinem Anzeigenanbieter. Hier ist ein Beispiel für die Implementierung mit dem Google Publisher-Tag.

window.opener-Referenzen vermeiden

Wenn in älteren Browsern eine Seite mit window.open() über einen Link mit target=_blank geöffnet wurde, ohne rel="noopener" anzugeben, enthielt die öffnende Seite einen Verweis auf das Fensterobjekt der geöffneten Seite.

Eine Seite mit einer nicht nullwertigen window.opener-Referenz stellt nicht nur ein Sicherheitsrisiko dar, sondern kann auch nicht sicher in den bfcache aufgenommen werden, da dies alle Seiten beeinträchtigen könnte, die darauf zugreifen.

Daher ist es am besten, window.opener-Referenzen zu erstellen. Verwenden Sie dazu nach Möglichkeit rel="noopener". Hinweis: Diese Option ist jetzt in allen modernen Browsern standardmäßig aktiviert. Wenn auf Ihrer Website ein Fenster geöffnet und über window.postMessage() gesteuert werden muss oder direkt auf das Fensterobjekt verwiesen wird, sind weder das geöffnete Fenster noch der Öffner für den bfcache geeignet.

Offene Verbindungen schließen, bevor der Nutzer die Seite verlässt

Wie bereits erwähnt, pausiert eine Seite, die sich im bfcache befindet, alle geplanten JavaScript-Aufgaben und setzt sie fort, wenn die Seite aus dem Cache entfernt wird.

Wenn diese geplanten JavaScript-Aufgaben nur auf DOM-APIs oder andere APIs zugreifen, die nur auf die aktuelle Seite beschränkt sind, führt das Pausieren dieser Aufgaben, während die Seite für den Nutzer nicht sichtbar ist, zu keinen Problemen.

Wenn diese Aufgaben jedoch mit APIs verbunden sind, auf die auch von anderen Seiten im selben Ursprung zugegriffen werden kann (z. B. IndexedDB, Web Locks, WebSockets), kann dies problematisch sein, da das Pausieren dieser Aufgaben dazu führen kann, dass Code auf anderen Tabs nicht ausgeführt wird.

Daher versuchen einige Browser in den folgenden Fällen nicht, eine Seite in den bfcache zu stellen:

Wenn auf deiner Seite eine dieser APIs verwendet wird, empfehlen wir dringend, Verbindungen zu schließen und Beobachter während des Ereignisses pagehide oder freeze zu entfernen oder zu trennen. So kann der Browser die Seite sicher im Cache speichern, ohne andere geöffnete Tabs zu beeinträchtigen.

Wenn die Seite dann aus dem bfcache wiederhergestellt wird, kannst du diese APIs während des Ereignisses pageshow oder resume wieder öffnen oder eine Verbindung dazu herstellen.

Das folgende Beispiel zeigt, wie Sie dafür sorgen können, dass Seiten, die IndexedDB verwenden, für bfcache infrage kommen, indem Sie eine offene Verbindung im pagehide-Event-Listener schließen:

let dbPromise;
function openDB() {
  if (!dbPromise) {
    dbPromise = new Promise((resolve, reject) => {
      const req = indexedDB.open('my-db', 1);
      req.onupgradeneeded = () => req.result.createObjectStore('keyval');
      req.onerror = () => reject(req.error);
      req.onsuccess = () => resolve(req.result);
    });
  }
  return dbPromise;
}

// Close the connection to the database when the user leaves.
window.addEventListener('pagehide', () => {
  if (dbPromise) {
    dbPromise.then(db => db.close());
    dbPromise = null;
  }
});

// Open the connection when the page is loaded or restored from bfcache.
window.addEventListener('pageshow', () => openDB());

Testen, ob die Seiten im Cache gespeichert werden können

Mit den Chrome DevTools können Sie Ihre Seiten testen, um sicherzustellen, dass sie für den bfcache optimiert sind, und Probleme erkennen, die die Eignung verhindern könnten.

So testen Sie eine Seite:

  1. Rufen Sie die Seite in Chrome auf.
  2. Klicken Sie in den Entwicklertools auf Anwendung -> Back-Forward-Cache.
  3. Klicken Sie auf die Schaltfläche Test ausführen. In den Entwicklertools wird dann versucht, zur Seite zu wechseln und wieder zurückzugehen, um festzustellen, ob die Seite aus dem bfcache wiederhergestellt werden kann.
Bereich „Back-Forward-Cache“ in den Entwicklertools
Im Bereich Back-Forward-Cache in den DevTools

Wenn der Test erfolgreich ist, wird im Steuerfeld „Aus dem Back-Forward-Cache wiederhergestellt“ angezeigt.

In den DevTools wird angezeigt, dass eine Seite aus dem bfcache wiederhergestellt wurde
Eine wiederhergestellte Seite.

Wenn sie nicht erfolgreich ist, wird im Steuerfeld der Grund dafür angegeben. Wenn Sie als Entwickler etwas gegen den Grund unternehmen können, wird er im Steuerfeld als Aktionierbar markiert.

In den Entwicklertools wird gemeldet, dass eine Seite nicht aus dem bfcache wiederhergestellt werden konnte
Ein fehlgeschlagener bfcache-Test mit einem umsetzbaren Ergebnis.

In diesem Beispiel ist die Seite aufgrund der Verwendung eines unload-Ereignis-Listeners nicht für den Back-Forward-Cache geeignet. Sie können das Problem beheben, indem Sie von unload zu pagehide wechseln:

Do
window.addEventListener('pagehide', ...);
Don'ts
window.addEventListener('unload', ...);

Lighthouse 10.0 hat einen bfcache-Audit hinzugefügt, der einen ähnlichen Test durchführt. Weitere Informationen finden Sie in der Dokumentation zum bfcache-Audit.

Auswirkungen von bfcache auf Analysen und Leistungsmessung

Wenn Sie die Zugriffe auf Ihre Website mit einem Analysetool erfassen, kann es sein, dass die Gesamtzahl der erfassten Seitenaufrufe sinkt, da Chrome den bfcache für mehr Nutzer aktiviert.

Wahrscheinlich werden in Ihren Berichten bereits zu wenige Seitenaufrufe von anderen Browsern erfasst, die BFCache implementieren, da viele gängige Analysebibliotheken BFCache-Wiederherstellungen nicht als neue Seitenaufrufe erfassen.

Wenn Sie BFCache-Wiederherstellungen in die Anzahl der Seitenaufrufe einbeziehen möchten, legen Sie Listener für das Ereignis pageshow fest und aktivieren Sie die Property persisted.

Im folgenden Beispiel wird gezeigt, wie das mit Google Analytics funktioniert. Andere Analysetools verwenden wahrscheinlich eine ähnliche Logik:

// Send a pageview when the page is first loaded.
gtag('event', 'page_view');

window.addEventListener('pageshow', (event) => {
  // Send another pageview if the page is restored from bfcache.
  if (event.persisted) {
    gtag('event', 'page_view');
  }
});

BFCache-Trefferquote messen

Sie können auch messen, ob der bfcache verwendet wurde, um Seiten zu identifizieren, auf denen er nicht genutzt wird. Dazu können Sie den Navigationstyp für Seitenaufrufe messen:

// Send a navigation_type when the page is first loaded.
gtag('event', 'page_view', {
   'navigation_type': performance.getEntriesByType('navigation')[0].type;
});

window.addEventListener('pageshow', (event) => {
  if (event.persisted) {
    // Send another pageview if the page is restored from bfcache.
    gtag('event', 'page_view', {
      'navigation_type': 'back_forward_cache';
    });
  }
});

Berechnen Sie die bfcache-Trefferquote anhand der Anzahl der back_forward- und back_forward_cache-Navigationen.

Es gibt eine Reihe von Szenarien, in denen der bfcache bei der Navigation zurück/vor nicht verwendet wird. Diese Szenarien liegen außerhalb der Kontrolle des Websiteinhabers. Dazu gehören:

  • wenn der Nutzer den Browser schließt und wieder öffnet
  • Wenn der Nutzer einen Tab dupliziert
  • Der Nutzer schließt einen Tab und öffnet ihn wieder.

In einigen dieser Fälle wird der ursprüngliche Navigationstyp von einigen Browsern beibehalten. Daher wird möglicherweise der Typ back_forward angezeigt, obwohl es sich dabei nicht um Rückwärtsnavigationen handelt.

Auch ohne diese Ausschlüsse wird der bfcache nach einer bestimmten Zeit verworfen, um Arbeitsspeicher zu sparen.

Websiteinhaber sollten also keine 100-prozentige BFCache-Trefferquote für alle back_forward-Navigationen erwarten. Die Messung ihres Verhältnisses kann jedoch nützlich sein, um Seiten zu identifizieren, bei denen die Seite selbst die bfcache-Nutzung bei einem hohen Anteil der Zurück- und Vorwärtsnavigationen verhindert.

Das Chrome-Team hat die NotRestoredReasons API hinzugefügt, um zu zeigen, warum Seiten bfcache nicht verwenden. So können Entwickler ihre bfcache-Trefferquoten verbessern. Das Chrome-Team hat Navigationstypen in CrUX hinzugefügt, sodass Sie die Anzahl der bfcache-Navigationen sehen können, ohne sie selbst zu messen.

Leistungsmessung

bfcache kann sich auch negativ auf die vor Ort erfassten Leistungsmesswerte auswirken, insbesondere auf Messwerte, die die Seitenladezeit messen.

Da bei bfcache-Navigationen eine vorhandene Seite wiederhergestellt wird, anstatt ein neues Seitenladen zu starten, wird die Gesamtzahl der erfassten Seitenladevorgänge verringert, wenn bfcache aktiviert ist. Wichtig ist jedoch, dass die Seitenladezeiten, die durch bfcache-Wiederherstellungen ersetzt werden, wahrscheinlich zu den schnellsten Seitenladezeiten in Ihrem Datensatz gehörten. Das liegt daran, dass Navigationen zurück und vorwärts per Definition wiederholte Besuche sind. Wiederholte Seitenladevorgänge sind in der Regel schneller als Seitenladevorgänge von Erstbesuchern (aufgrund des HTTP-Cachings, wie bereits erwähnt).

Das führt zu weniger schnellen Seitenladezeiten in Ihrem Datensatz, was die Verteilung wahrscheinlich verzögert – trotz der Tatsache, dass sich die Leistung für den Nutzer wahrscheinlich verbessert hat.

Es gibt verschiedene Möglichkeiten, mit diesem Problem umzugehen. Eine Möglichkeit besteht darin, alle Messwerte für das Laden von Seiten mit dem jeweiligen Navigationstyp zu versehen: navigate, reload, back_forward oder prerender. So können Sie die Leistung in diesen Navigationstypen weiter im Blick behalten, auch wenn die Gesamtverteilung negativ ausfällt. Wir empfehlen diesen Ansatz für nicht nutzerorientierte Seitenlademesswerte wie die Zeit bis zum ersten Byte (TTFB).

Bei nutzerorientierten Messwerten wie den Core Web Vitals ist es besser, einen Wert anzugeben, der die Nutzererfahrung genauer widerspiegelt.

Auswirkungen auf die Core Web Vitals

Mit den Core Web Vitals wird die Nutzerfreundlichkeit einer Webseite in verschiedenen Dimensionen (Ladegeschwindigkeit, Interaktivität, visuelle Stabilität) gemessen. Da Nutzer die Wiederherstellung des bfcache als schnellere Navigation als das Laden der gesamten Seite empfinden, ist es wichtig, dass die Core Web Vitals-Messwerte dies widerspiegeln. Schließlich ist es für Nutzer nicht wichtig, ob der bfcache aktiviert wurde. Sie möchten nur, dass die Navigation schnell ist.

Bei Tools wie dem Bericht zur Nutzererfahrung in Chrome, in denen Core Web Vitals-Messwerte erfasst und in Berichte aufgenommen werden, werden bfcache-Wiederherstellungen im Dataset als separate Seitenaufrufe behandelt. Es gibt zwar keine eigenen Web-Performance-APIs für die Messung dieser Messwerte nach bfcache-Wiederherstellungen, aber Sie können deren Werte mit vorhandenen Web-APIs schätzen:

  • Verwenden Sie für Largest Contentful Paint (LCP) das Delta zwischen dem Zeitstempel des Ereignisses pageshow und dem Zeitstempel des nächsten gerenderten Frames, da alle Elemente im Frame gleichzeitig gerendert werden. Bei der Wiederherstellung des bfcache stimmen LCP und FCP überein.
  • Verwenden Sie für Interaction to Next Paint (INP) den vorhandenen Performance Observer, aber setzen Sie den aktuellen INP-Wert auf 0 zurück.
  • Verwenden Sie für Cumulative Layout Shift (CLS) den vorhandenen Performance Observer, setzen Sie den aktuellen CLS-Wert jedoch auf 0 zurück.

Weitere Informationen dazu, wie sich bfcache auf die einzelnen Messwerte auswirkt, finden Sie in den Anleitungen zu den einzelnen Core Web Vitals-Messwerten. Ein konkretes Beispiel für die Implementierung der bfcache-Versionen dieser Messwerte findest du in der PR-Dokumentation zum Hinzufügen zur Webvitals-JS-Bibliothek.

Die JavaScript-Bibliothek web-vitals unterstützt die Wiederherstellung des bfcache in den Messwerten, die sie erfasst.

Zusätzliche Ressourcen