Back-Forward-Cache

Der Back-Forward-Cache (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) wird eine Seite nicht zerstört, wenn der Nutzer zu einer anderen Seite wechselt. Stattdessen wird die Zerstörung verschoben und die JS-Ausführung pausiert. Wenn der Nutzer bald wieder 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 beim Laden der vorherigen Seite ausmachen:

Ohne bfcache aktiviert 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 dem bfcache werden Seiten beim Zurück- und Vorwärtsnavigieren viel schneller geladen.

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

bfcache beschleunigt nicht nur die Navigation, sondern reduziert 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 auf zuvor gestellte Anfragen enthält. Da es sehr selten vorkommt, dass alle Anfragen, die zum Laden einer Seite erforderlich sind, aus dem HTTP-Cache erfüllt werden, 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 gehen Sie beispielsweise mit setTimeout()-Aufrufen um, bei denen die Zeitüberschreitung erreicht wird, während sich die Seite im bfcache befindet?

Die Antwort ist, dass Browser alle ausstehenden Timer oder nicht aufgelösten Versprechen für Seiten im bfcache pausieren, einschließlich fast aller ausstehenden Aufgaben in den JavaScript-Aufgabenwarteschlangen, und die Verarbeitung von Aufgaben 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 in einem iFrame 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 die App von vorn herein 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, wann eine Seite aus dem 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 Leistungsmessung.

Beobachten, wann eine Seite in den bfcache aufgenommen wird

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

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 beabsichtigt, die Seite im Cache zu speichern, es aber andere Faktoren geben kann, die das Speichern im Cache unmöglich machen.

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 aber 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 Entwickler wissen, welche Seiten für den bfcache infrage kommen und welche nicht, um die Cache-Trefferquote zu maximieren.

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

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. Niemals!

Das Ereignis unload ist für Browser problematisch, da es älter als bfcache ist und viele Seiten im Internet davon ausgehen (was durchaus vernünftig ist), 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-Ereignis-Listener im Cache zu speichern, da das Risiko von Fehlern 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.unload Das Ereignis pagehide wird in allen Fällen ausgelöst, in denen das Ereignis unload ausgelöst wird. Es wird auch ausgelöst, wenn eine Seite in den bfcache aufgenommen 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.

Permissions-Policy: unload=()

Außerdem wird verhindert, dass Drittanbieter oder Erweiterungen die Website verlangsamen, indem sie Entlade-Handler hinzufügen und die Website für den bfcache unzulässig machen.

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 Verwendungsmöglichkeiten 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 in Antworten festlegen können, um den Browser anzuweisen, 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.

Der bfcache ist zwar kein HTTP-Cache, aber wenn Cache-Control: no-store für die Seitenressource selbst festgelegt ist (im Gegensatz zu einer Unterressource), speichern Browser die Seite in der Regel nicht im bfcache. Daher können Seiten, auf denen Cache-Control: no-store verwendet wird, möglicherweise nicht für den bfcache verwendet werden. 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, bei denen das Caching in keiner Form angemessen 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, geschieht dies aus dem Arbeitsspeicher, nicht aus dem HTTP-Cache. 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 auf Ihrer Website der Nutzerstatus gespeichert wird, 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 vorwärts 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 sollten Sie window.opener-Referenzen vermeiden. 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.

Schließen Sie offene Verbindungen, bevor der Nutzer die Seite verlässt.

Wie bereits erwähnt, werden alle geplanten JavaScript-Aufgaben pausiert, wenn eine Seite im bfcache gehalten wird, und fortgesetzt, 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 Ihrer 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 die Verbindung zu ihnen zu trennen. So kann der Browser die Seite sicher im Cache speichern, ohne dass andere geöffnete Tabs davon betroffen sind.

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.

Im folgenden Beispiel wird gezeigt, wie Sie dafür sorgen, dass Seiten mit IndexedDB für den bfcache infrage kommen, indem Sie eine offene Verbindung im pagehide-Ereignislistener 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());

Prüfen, ob Ihre 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 der Vorgang fehlschlägt, wird im Steuerfeld der Grund dafür angezeigt. 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 bfcache geeignet. Sie können das Problem beheben, indem Sie von unload zu pagehide wechseln:

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

In Lighthouse 10.0 wurde außerdem eine BFCache-Prüfung hinzugefügt, die einen ähnlichen Test durchführt. Weitere Informationen finden Sie in der Dokumentation zur bfcache-Prüfung.

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, richten Sie Listener für das Ereignis pageshow ein 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 Navigationen vom Typ back_forward und back_forward_cache.

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
  • wenn der Nutzer einen Tab schließt und wieder öffnet

In einigen dieser Fälle wird der ursprüngliche Navigationstyp von einigen Browsern beibehalten und es wird möglicherweise eine Art back_forward angezeigt, obwohl es sich nicht um eine Navigation zurück oder vorwärts 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. Das Verhältnis kann jedoch nützlich sein, um Seiten zu identifizieren, auf denen die Seite selbst die Nutzung des bfcache bei einem hohen Anteil der Navigationen zurück und vor verhindert.

Das Chrome-Team hat die NotRestoredReasons API hinzugefügt, um die Gründe dafür aufzuzeigen, warum Seiten den bfcache nicht verwenden. So können Entwickler ihre bfcache-Trefferquoten verbessern. Das Chrome-Team hat außerdem Navigationstypen zu CrUX hinzugefügt, sodass Sie die Anzahl der bfcache-Navigationen auch sehen können, ohne sie selbst messen zu müssen.

Leistungsmessung

bfcache kann sich auch negativ auf die im Feld erfassten Leistungsmesswerte auswirken, insbesondere auf Messwerte zur Seitenladezeit.

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.

In Tools, in denen die Core Web Vitals-Messwerte erfasst und in Berichten verwendet werden, wie etwa im Bericht zur Nutzererfahrung in Chrome, werden BFCache-Wiederherstellungen in ihrem Datensatz als separate Seitenaufrufe behandelt. Es gibt zwar keine speziellen Web-Leistungs-APIs zum Erfassen dieser Messwerte nach der Wiederherstellung des bfcache, aber Sie können ihre Werte mithilfe vorhandener Web-APIs annähernd ermitteln:

  • 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) Ihren vorhandenen Leistungsmesswert, setzen Sie den aktuellen INP-Wert jedoch auf 0 zurück.
  • Verwenden Sie für den Cumulative Layout Shift (CLS) Ihren vorhandenen Leistungsmesswert, 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 von bfcache-Versionen dieser Messwerte finden Sie im PR, mit dem sie der JS-Bibliothek für Web Vitals hinzugefügt wurden.

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

Zusätzliche Ressourcen