Der Back-Forward-Cache (bfcache) ist eine Browseroptimierung, die eine sofortige Rückwärts- und Vorwärtsnavigation ermöglicht. Dadurch wird das Surfen für Nutzer erheblich verbessert, insbesondere für langsamere Netzwerke oder Geräte.
Als Webentwickler ist es wichtig, dass Sie wissen, wie Sie Ihre Seiten für den bfcache optimieren, damit Ihre Nutzer davon profitieren können.
Browserkompatibilität
Alle wichtigen Browser enthalten einen bfcache, darunter Chrome ab Version 96, Firefox und Safari.
bfcache-Grundlagen
Beim Back-Forward-Cache (bfcache) wird eine Seite nicht sofort zerstört, wenn der Nutzer sie verlässt. Stattdessen wird die Zerstörung aufgeschoben und die JS-Ausführung pausiert. Wenn der Nutzer schnell zurückkehrt, machen wir die Seite wieder sichtbar und setzen die JS-Ausführung fort. Dadurch wird die Seite für den Nutzer nahezu sofort aufgerufen.
Wie oft haben Sie eine Website besucht und auf einen Link geklickt, um zu einer anderen Seite zu gelangen, nur um dann festzustellen, dass es nicht das war, was Sie wollten, und auf die Schaltfläche „Zurück“ geklickt? In diesem Moment kann der Back-Forward-Cache einen großen Unterschied bei der Ladegeschwindigkeit der vorherigen Seite machen:
| Ohne aktivierten bfcache | Eine neue Anfrage wird 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) der gerade heruntergeladenen Ressourcen noch einmal herunterladen, parsen und ausführen. |
| Mit aktiviertem bfcache | Das Laden der vorherigen Seite erfolgt im Grunde sofort, da die gesamte Seite aus dem Arbeitsspeicher wiederhergestellt werden kann, ohne dass auf das Netzwerk zugegriffen werden muss. |
In diesem Video sehen Sie, wie der Back-Forward-Cache funktioniert und wie er die Navigation beschleunigen kann:
Im Video ist das Beispiel mit dem Back-Forward-Cache deutlich schneller als das Beispiel ohne.
Der bfcache beschleunigt nicht nur die Navigation, sondern reduziert auch die Datennutzung, da Ressourcen nicht noch einmal heruntergeladen werden müssen.
Die Chrome-Nutzungsdaten zeigen, dass 10 % der Navigationen auf Computern und 20 % auf Mobilgeräten entweder „Zurück“ oder „Vorwärts“ sind. Wenn der bfcache aktiviert ist, können Browser jeden Tag die Datenübertragung und die Ladezeit für Milliarden von Webseiten vermeiden.
Funktionsweise des Cache
Der von bfcache verwendete Cache unterscheidet sich vom HTTP-Cache, der eine eigene Rolle bei der Beschleunigung wiederholter Navigationsvorgänge spielt. Der 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 in Bezug auf die bestmögliche Aufbewahrung von Code, der gerade bearbeitet wird, mit einigen Komplexitäten verbunden. Wie gehen Sie beispielsweise mit setTimeout()-Aufrufen um, bei denen das Zeitlimit erreicht wird, während sich die Seite im bfcache befindet?
Die Antwort lautet, dass Browser alle ausstehenden Timer oder nicht aufgelösten Promises für Seiten im bfcache pausieren, einschließlich fast aller ausstehenden Aufgaben in den JavaScript-Aufgabenwarteschlangen. Die Verarbeitung von Aufgaben wird fortgesetzt, wenn die Seite aus dem bfcache wiederhergestellt wird.
In einigen Fällen, z. B. bei Zeitüberschreitungen und Promises, ist das Risiko relativ gering. In anderen Fällen kann es jedoch zu verwirrendem oder unerwartetem Verhalten kommen. Wenn der Browser beispielsweise eine Aufgabe pausiert, die im Rahmen einer IndexedDB-Transaktion erforderlich ist, kann sich das auf andere geöffnete Tabs desselben Ursprungs auswirken, da auf dieselben IndexedDB-Datenbanken gleichzeitig über mehrere Tabs zugegriffen werden kann. Daher versuchen Browser in der Regel nicht, Seiten während einer IndexedDB-Transaktion oder bei Verwendung von APIs, die sich auf andere Seiten auswirken könnten, im Cache zu speichern.
Weitere Informationen dazu, wie sich die Verwendung verschiedener APIs auf die bfcache-Eignung einer Seite auswirkt, finden Sie unter Seiten für bfcache optimieren.
bfcache und iFrames
Wenn eine Seite eingebettete iFrames enthält, können die iFrames selbst nicht separat für den bfcache verwendet werden. Wenn Sie beispielsweise in einem iFrame zu einer anderen URL wechseln, werden die vorherigen Inhalte nicht im bfcache gespeichert. Wenn Sie dann zurückgehen, wechselt der Browser im iFrame und nicht im Hauptframe zurück. Die Rückwärtsnavigation im iFrame verwendet jedoch nicht den bfcache.
Wenn der Hauptframe jedoch aus dem bfcache wiederhergestellt wird, werden eingebettete iFrames so wiederhergestellt, wie sie waren, als die Seite in den bfcache aufgenommen wurde.
Auch der Hauptframe kann daran gehindert werden, den bfcache zu verwenden, wenn in einem eingebetteten iFrame APIs verwendet werden, die dies verhindern. Dies lässt sich durch die Berechtigungsrichtlinie, die für den Hauptframe festgelegt ist, oder durch die Verwendung von sandbox-Attributen vermeiden.
Der bfcache und Single-Page-Anwendungen (SPAs)
Da der bfcache mit vom Browser verwalteten Navigationen funktioniert, ist er nicht für „Soft Navigations“ in einer Single-Page-App (SPA) geeignet. Der bfcache kann jedoch weiterhin hilfreich sein, wenn Sie zu einer SPA zurückkehren, anstatt die App von Anfang an neu zu initialisieren.
APIs zur Beobachtung von bfcache
Der bfcache ist zwar eine Optimierung, die Browser automatisch vornehmen, aber es ist trotzdem wichtig, dass Entwickler wissen, wann er verwendet wird. So können sie ihre Seiten entsprechend optimieren und alle Messwerte oder Leistungsmessungen anpassen.
Die primären Ereignisse, die zur Beobachtung von bfcache verwendet werden, sind die Seitenübergangsereignisse pageshow und pagehide, die von den meisten Browsern unterstützt werden.
Die neueren Page Lifecycle-Ereignisse (freeze und resume) werden auch ausgelöst, wenn Seiten in den bfcache eintreten oder ihn 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 pageshow-Ereignis wird direkt nach dem load-Ereignis ausgelöst, wenn die Seite zum ersten Mal geladen wird und jedes Mal, wenn die Seite aus dem Back-Forward-Cache wiederhergestellt wird. Das pageshow-Ereignis hat das Attribut persisted, das true ist, wenn die Seite aus bfcache wiederhergestellt wurde, und false, wenn dies nicht der Fall ist. Mit der Eigenschaft persisted können Sie normale Seitenaufrufe 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 resume-Ereignis ausgelöst, wenn Seiten aus dem bfcache wiederhergestellt werden (unmittelbar vor dem pageshow-Ereignis) und wenn ein Nutzer einen eingefrorenen Hintergrundtab wieder aufruft. Wenn Sie den Status einer Seite aktualisieren möchten, nachdem sie eingefroren wurde (einschließlich Seiten im bfcache), können Sie das resume-Ereignis verwenden. Wenn Sie die bfcache-Trefferrate Ihrer Website messen möchten, müssen Sie das pageshow-Ereignis 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 Wie sich bfcache auf Analytics und die Leistungsmessung auswirkt.
Beobachten, wann eine Seite in den bfcache wechselt
Das pagehide-Ereignis wird entweder ausgelöst, wenn eine Seite entladen wird, oder wenn der Browser versucht, sie im BF-Cache zu speichern.
Das pagehide-Ereignis hat auch das Attribut persisted. Wenn der Wert false ist, können Sie davon ausgehen, dass die Seite nicht in den bfcache aufgenommen wird. persisted ist true, aber das bedeutet nicht, dass eine Seite im Cache gespeichert wird. Das bedeutet, dass der Browser beabsichtigt, die Seite im Cache zu speichern. Es kann jedoch andere Faktoren geben, die dies 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.');
}
});
Ebenso wird das freeze-Ereignis unmittelbar nach dem pagehide-Ereignis ausgelöst, wenn persisted true ist. Das bedeutet jedoch nur, dass der Browser beabsichtigt, die Seite im Cache zu speichern. Aus verschiedenen Gründen, die später erläutert werden, muss sie sie möglicherweise trotzdem verwerfen.
Seiten für den bfcache optimieren
Nicht alle Seiten werden im bfcache gespeichert und 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-Trefferraten zu maximieren.
In den folgenden Abschnitten werden die Best Practices beschrieben, mit denen Sie die Wahrscheinlichkeit erhöhen, dass der Browser Ihre Seiten im Cache speichern kann.
unload-Ereignis niemals verwenden
Die wichtigste Methode zur Optimierung für bfcache in allen Browsern besteht darin, das unload-Ereignis niemals zu verwenden. Immer!
Das unload-Ereignis ist für Browser problematisch, da es vor dem bfcache-Mechanismus eingeführt wurde. Viele Seiten im Internet gehen (berechtigterweise) davon aus, dass eine Seite nach dem Auslösen des unload-Ereignisses nicht mehr vorhanden ist. Das ist eine Herausforderung, da viele dieser Seiten auch in der Annahme erstellt wurden, dass das unload-Ereignis immer ausgelöst wird, wenn ein Nutzer die Seite verlässt. Das ist aber nicht mehr der Fall und war es auch schon lange nicht.
Browser stehen also vor einem Dilemma: Sie müssen sich zwischen etwas entscheiden, das die Nutzerfreundlichkeit verbessern, aber auch das Risiko bergen kann, dass die Seite nicht mehr richtig funktioniert.
Auf dem Desktop haben Chrome und Firefox entschieden, Seiten als nicht für den BFCache geeignet zu kennzeichnen, wenn sie einen unload-Listener hinzufügen. Das ist weniger riskant, schließt aber auch viele Seiten aus. Safari versucht, einige Seiten mit einem unload-Ereignis-Listener im Cache zu speichern. Um jedoch potenzielle Fehler zu vermeiden, wird das unload-Ereignis 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 zu cachen, da das Risiko von Fehlern geringer ist. Das liegt daran, dass das unload-Event auf Mobilgeräten schon immer extrem unzuverlässig war. In Firefox können Seiten, auf denen unload verwendet wird, den Back-Forward-Cache nicht verwenden. Das gilt nicht für iOS, da dort alle Browser die WebKit-Rendering-Engine verwenden müssen und sich daher wie Safari verhalten.
Verwenden Sie anstelle des unload-Ereignisses das pagehide-Ereignis. 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 im bfcache gespeichert wird.
Lighthouse bietet einen no-unload-listeners-Audit, der Entwickler warnt, wenn JavaScript auf ihren Seiten (einschließlich des JavaScript von Drittanbieterbibliotheken) einen unload-Ereignis-Listener hinzufügt.
Aufgrund der Unzuverlässigkeit und der Auswirkungen auf die Leistung für bfcache plant Chrome, das unload-Ereignis einzustellen.
Verwenden Sie die Berechtigungsrichtlinie, um zu verhindern, dass Unload-Handler auf einer Seite verwendet werden.
Auf Websites, auf denen keine unload-Ereignishandler verwendet werden, kann mit einer Berechtigungsrichtlinie dafür gesorgt werden, dass diese nicht hinzugefügt werden.
Permissions-Policy: unload=()
Außerdem wird so verhindert, dass Drittanbieter oder Erweiterungen die Website verlangsamen, indem sie Unload-Handler hinzufügen und die Website für den bfcache ungeeignet machen.
beforeunload-Listener nur bedingt hinzufügen
Das Ereignis beforeunload führt nicht dazu, dass Ihre Seiten in modernen Browsern nicht für den Back-Forward-Cache infrage kommen. Früher war das jedoch der Fall und es ist immer noch unzuverlässig. Vermeiden Sie es daher, es zu verwenden, es sei denn, es ist unbedingt erforderlich.
Im Gegensatz zum unload-Ereignis gibt es jedoch legitime Anwendungsfälle für beforeunload. Sie möchten den Nutzer beispielsweise warnen, dass er nicht gespeicherte Änderungen verliert, wenn er die Seite verlässt. In diesem Fall empfiehlt es sich, nur dann beforeunload-Listener hinzuzufügen, wenn ein Nutzer nicht gespeicherte Änderungen hat, und sie sofort zu entfernen, nachdem die nicht gespeicherten Änderungen gespeichert wurden.
window.addEventListener('beforeunload', (event) => { if (pageHasUnsavedChanges()) { event.preventDefault(); return event.returnValue = 'Are you sure you want to exit?'; } });
beforeunload-Listener bedingungslos hinzugefügt.
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); });
beforeunload-Listener nur bei Bedarf hinzugefügt und wieder entfernt, wenn er nicht mehr 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 mit vertraulichen Nutzerinformationen verwendet, z. B. für Seiten, die nur nach der Anmeldung aufgerufen werden können.
Der Back-Forward-Cache ist zwar kein HTTP-Cache, aber in der Vergangenheit haben Browser Seiten nicht im Back-Forward-Cache gespeichert, wenn Cache-Control: no-store für die Seitenressource selbst (im Gegensatz zu einer untergeordneten Ressource) festgelegt wurde. Daher können Seiten, auf denen Cache-Control: no-store verwendet wird, möglicherweise nicht im Back-Forward-Cache gespeichert werden. Es wird derzeit daran gearbeitet, dieses Verhalten für Chrome datenschutzfreundlich zu ändern.
Da Cache-Control: no-store die Eignung einer Seite für bfcache einschränkt, sollte es nur auf Seiten mit vertraulichen Informationen festgelegt werden, auf denen Caching jeglicher Art nicht angebracht ist.
Verwenden Sie Cache-Control: no-cache oder Cache-Control: max-age=0 für Seiten, auf denen immer aktuelle Inhalte präsentiert werden müssen und die keine vertraulichen Informationen enthalten. Diese Anweisungen weisen den Browser an, die Inhalte neu zu validieren, bevor sie bereitgestellt werden. Sie wirken sich nicht auf die Eignung einer Seite für den bfcache aus.
Wenn eine Seite aus dem Back-Forward-Cache wiederhergestellt wird, geschieht dies aus dem Arbeitsspeicher und nicht aus dem HTTP-Cache. Daher werden Direktiven 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.
Das ist aber wahrscheinlich immer noch besser für die Nutzer, da bfcache-Wiederherstellungen sofort erfolgen und die Inhalte nicht sehr lange im bfcache bleiben. Es ist also unwahrscheinlich, dass die Inhalte veraltet sind. Wenn sich Ihre Inhalte jedoch minütlich ändern, können Sie alle Aktualisierungen mit dem pageshow-Ereignis abrufen, wie im nächsten Abschnitt beschrieben.
Veraltete oder sensible Daten nach der bfcache-Wiederherstellung aktualisieren
Wenn auf Ihrer Website der Nutzerstatus beibehalten wird, insbesondere vertrauliche Nutzerinformationen, müssen diese Daten aktualisiert oder gelöscht werden, nachdem eine Seite aus dem BFCache wiederhergestellt wurde.
Wenn ein Nutzer beispielsweise zur Abrechnungsseite navigiert und dann seinen Einkaufswagen aktualisiert, könnten durch die Rückwärtsnavigation möglicherweise veraltete Informationen angezeigt werden, wenn eine alte Seite aus dem bfcache wiederhergestellt wird.
Ein weiteres, kritischeres Beispiel: Ein Nutzer meldet sich auf einem öffentlichen Computer von einer Website ab und der nächste Nutzer klickt auf die Schaltfläche „Zurück“. Dadurch könnten private Daten offengelegt werden, von denen der Nutzer angenommen hat, dass sie beim Abmelden gelöscht wurden.
Um solche Situationen zu vermeiden, sollten Sie die Seite nach einem pageshow-Ereignis immer aktualisieren, wenn event.persisted true ist:
window.addEventListener('pageshow', (event) => {
if (event.persisted) {
// Do any checks and updates to the page
}
});
Im Idealfall aktualisieren Sie den Inhalt direkt. Bei einigen Änderungen kann es jedoch sinnvoll sein, ein vollständiges Neuladen zu erzwingen. Im folgenden Code wird geprüft, ob im pageshow-Ereignis ein websitespezifisches Cookie vorhanden ist. Wenn das Cookie nicht gefunden wird, wird die Seite neu geladen:
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 beibehalten wird (um Vorwärtsnavigationen zu ermöglichen). In einigen Fällen ist eine Weiterleitung jedoch besser geeignet.
Anzeigen und bfcache-Wiederherstellung
Es kann verlockend sein, die Verwendung von bfcache zu vermeiden, um bei jeder Rückwärts-/Vorwärtsnavigation neue Anzeigen auszuliefern. Ein solches Verhalten kann sich jedoch nicht nur auf die Leistung auswirken, sondern es ist auch fraglich, ob es zu einem besseren Engagement mit Anzeigen führt. Nutzer haben möglicherweise eine Anzeige gesehen, auf die sie später klicken wollten. Wenn sie die Seite jedoch neu laden, anstatt sie aus dem BF-Cache wiederherzustellen, ist das nicht möglich. Es ist wichtig, dieses Szenario zu testen, idealerweise mit einem A/B-Test, bevor Sie Annahmen treffen.
Wenn Anzeigen auf Websites bei der Wiederherstellung aus dem bfcache aktualisiert werden sollen, kann dies durch Aktualisieren der Anzeigen beim pageshow-Ereignis erfolgen, wenn event.persisted gleich true ist. So wird die Seitenleistung nicht beeinträchtigt. Fragen Sie Ihren Anzeigenanbieter. Hier finden Sie ein Beispiel dafür, wie Sie das mit dem Google Publisher-Tag tun können.
window.opener-Referenzen vermeiden
In älteren Browsern hatte die öffnende Seite einen Verweis auf das Fensterobjekt der geöffneten Seite, wenn eine Seite mit window.open() über einen Link mit target=_blank geöffnet wurde, ohne dass rel="noopener" angegeben wurde.
Eine Seite mit einem window.opener-Verweis, der nicht null ist, stellt nicht nur ein Sicherheitsrisiko dar, sondern kann auch nicht sicher im Back-Forward-Cache gespeichert werden, da dies zu Problemen auf Seiten führen könnte, die darauf zugreifen.
Daher sollten Sie window.opener-Referenzen möglichst vermeiden. Verwenden Sie dazu nach Möglichkeit immer rel="noopener". Das ist jetzt der Standard in allen modernen Browsern. Wenn auf Ihrer Website ein Fenster geöffnet und über window.postMessage() gesteuert oder direkt auf das Fensterobjekt verwiesen wird, ist weder das geöffnete Fenster noch das öffnende Fenster für den Back-Forward-Cache geeignet.
Offene Verbindungen schließen, bevor der Nutzer die Seite verlässt
Wie bereits erwähnt, werden alle geplanten JavaScript-Aufgaben angehalten, wenn eine Seite im BF-Cache gespeichert wird. Sie werden fortgesetzt, wenn die Seite aus dem Cache entfernt wird.
Wenn diese geplanten JavaScript-Aufgaben nur auf DOM-APIs oder andere APIs zugreifen, die 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 desselben Ursprungs zugegriffen werden kann (z. B. IndexedDB, Web Locks, WebSockets), kann dies problematisch sein, da das Pausieren dieser Aufgaben die Ausführung von Code in anderen Tabs verhindern kann.
Daher versuchen einige Browser in den folgenden Szenarien nicht, eine Seite im BF-Cache zu speichern:
- Seiten mit einer offenen IndexedDB-Verbindung
- Seiten mit laufenden fetch()- oder XMLHttpRequest-Vorgängen
- Seiten mit einer offenen WebSocket- oder WebRTC-Verbindung
Wenn auf Ihrer Seite eine dieser APIs verwendet wird, empfehlen wir dringend, Verbindungen zu schließen und Beobachter während des pagehide- oder freeze-Ereignisses zu entfernen oder zu trennen. So kann der Browser die Seite sicher im Cache speichern, ohne dass dies Auswirkungen auf andere geöffnete Tabs hat.
Wenn die Seite dann aus dem bfcache wiederhergestellt wird, können Sie die Verbindung zu diesen APIs während des pageshow- oder resume-Ereignisses wieder öffnen oder herstellen.
Das folgende Beispiel zeigt, wie Sie dafür sorgen, dass Seiten, auf denen IndexedDB verwendet wird, für den 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());
Prüfen, ob Ihre Seiten im Cache gespeichert werden können
Mit den Chrome-Entwicklertools können Sie Ihre Seiten testen, um sicherzustellen, dass sie für den Back-Forward-Cache optimiert sind, und Probleme erkennen, die die Eignung verhindern.
So testen Sie eine Seite:
- Rufen Sie die Seite in Chrome auf.
- Rufen Sie in den Entwicklertools Anwendung > Cache für Zurück-/Vorwärts-Schaltflächen auf.
- Klicken Sie auf die Schaltfläche Test ausführen. Die Entwicklertools versuchen dann, die Seite zu verlassen und wieder aufzurufen, um festzustellen, ob sie aus dem Back-Forward-Cache wiederhergestellt werden kann.
Wenn der Test erfolgreich ist, wird im Bereich „Aus Back-Forward-Cache wiederhergestellt“ angezeigt.
Wenn die Überprüfung nicht erfolgreich ist, wird im Bereich der Grund dafür angegeben. Wenn der Grund etwas ist, das Sie als Entwickler beheben können, wird er im Bereich als Actionable (Umsetzbar) gekennzeichnet.
In diesem Beispiel wird die Seite durch die Verwendung eines unload-Event-Listeners nicht für den Back-Forward-Cache infrage kommend. Sie können das Problem beheben, indem Sie von unload zu pagehide wechseln:
window.addEventListener('pagehide', ...);
window.addEventListener('unload', ...);
In Lighthouse 10.0 wurde auch eine bfcache-Prüfung hinzugefügt, die einen ähnlichen Test durchführt. Weitere Informationen finden Sie in der Dokumentation zum bfcache-Audit.
Auswirkungen von bfcache auf Analytics und Leistungsmessung
Wenn Sie ein Analysetool verwenden, um Besuche auf Ihrer Website zu erfassen, stellen Sie möglicherweise einen Rückgang der Gesamtzahl der gemeldeten Seitenaufrufe fest, da Chrome den bfcache für immer mehr Nutzer aktiviert.
Tatsächlich werden Seitenaufrufe aus anderen Browsern, in denen bfcache implementiert ist, wahrscheinlich bereits untererfasst, da viele beliebte Analytikbibliotheken bfcache-Wiederherstellungen nicht als neue Seitenaufrufe erfassen.
Wenn Sie bfcache-Wiederherstellungen in Ihre Seitenaufrufzahlen einbeziehen möchten, legen Sie Listener für das pageshow-Ereignis fest und prüfen Sie die persisted-Eigenschaft.
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
Möglicherweise möchten Sie auch messen, ob der Back-Forward-Cache 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-Trefferrate anhand der Anzahl der back_forward- und back_forward_cache-Navigationen.
Es ist wichtig zu wissen, dass es eine Reihe von Szenarien gibt, die nicht im Einflussbereich des Websiteinhabers liegen und in denen bei der Vorwärts-/Rückwärtsnavigation kein bfcache verwendet wird. Dazu gehören:
- Wenn der Nutzer den Browser schließt und wieder öffnet
- Ein Nutzer dupliziert einen Tab.
- Wenn der Nutzer einen Tab schließt und wieder öffnet
In einigen dieser Fälle wird der ursprüngliche Navigationstyp von einigen Browsern beibehalten. Daher kann es sein, dass ein Typ von back_forward angezeigt wird, obwohl es sich nicht um Rückwärts-/Vorwärtsnavigationen handelt.
Auch ohne diese Ausschlüsse wird der bfcache nach einer gewissen Zeit verworfen, um Arbeitsspeicher zu sparen.
Websiteinhaber sollten daher nicht mit einer 100-prozentigen bfcache-Trefferquote für alle back_forward-Navigationen rechnen. Das Verhältnis kann jedoch nützlich sein, um Seiten zu identifizieren, auf denen die Seite selbst die bfcache-Nutzung für einen hohen Anteil der Vor- und Zurück-Navigationen verhindert.
Das Chrome-Team hat die NotRestoredReasons API hinzugefügt, um die Gründe dafür aufzuzeigen, warum Seiten keinen Back-Forward-Cache verwenden. So können Entwickler ihre Trefferquoten für den Back-Forward-Cache verbessern. Das Chrome-Team hat CrUX auch Navigationstypen hinzugefügt. So können Sie die Anzahl der bfcache-Navigationen sehen, ohne sie selbst zu messen.
Leistungsmessung
Der BFCache kann sich auch negativ auf Leistungsmesswerte auswirken, die im Feld erfasst werden, insbesondere auf Messwerte, mit denen die Seitenladezeiten gemessen werden.
Da beim Back-Forward-Cache (bfcache) eine vorhandene Seite wiederhergestellt und nicht eine neue Seite geladen wird, sinkt die Gesamtzahl der erfassten Seitenladevorgänge, wenn der bfcache aktiviert ist. Wichtig ist jedoch, dass die Seitenaufrufe, die durch bfcache-Wiederherstellungen ersetzt werden, wahrscheinlich zu den schnellsten Seitenaufrufen in Ihrem Datensatz gehören. Das liegt daran, dass Vor- und Zurück-Navigationen per Definition wiederholte Besuche sind. Wiederholte Seitenaufrufe sind in der Regel schneller als Seitenaufrufe von Erstbesuchern (aufgrund des HTTP-Caching, wie bereits erwähnt).
Das Ergebnis sind weniger schnelle Seitenaufrufe in Ihrem Datensatz, was die Verteilung wahrscheinlich verlangsamt – obwohl sich die Leistung für den Nutzer wahrscheinlich verbessert hat.
Es gibt verschiedene Möglichkeiten, dieses Problem zu beheben. 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 bei diesen Navigationstypen weiterhin im Blick behalten, auch wenn die Gesamtverteilung negativ ausfällt. Wir empfehlen diesen Ansatz für nicht nutzerorientierte Seitenlade-Messwerte wie Time to First Byte (TTFB).
Bei nutzerorientierten Messwerten wie den Core Web Vitals ist es besser, einen Wert zu melden, der die Nutzererfahrung genauer widerspiegelt.
Auswirkungen auf die Core Web Vitals
Core Web Vitals messen die Nutzerfreundlichkeit einer Webseite in verschiedenen Dimensionen (Ladegeschwindigkeit, Interaktivität, visuelle Stabilität). Da Nutzer bfcache-Wiederherstellungen als schnellere Navigationen als vollständige Seitenladevorgänge wahrnehmen, ist es wichtig, dass die Core Web Vitals-Messwerte dies widerspiegeln. Ein Nutzer interessiert sich nicht dafür, ob der bfcache aktiviert war oder nicht. Er möchte nur, dass die Navigation schnell ist.
Tools, mit denen die Core Web Vitals-Messwerte erfasst und gemeldet werden, z. B. der Bericht zur Nutzererfahrung in Chrome, behandeln bfcache-Wiederherstellungen in ihrem Datensatz als separate Seitenaufrufe. Es gibt zwar keine speziellen Web-Performance-APIs zum Messen dieser Messwerte nach bfcache-Wiederherstellungen, aber Sie können ihre Werte mit vorhandenen Web-APIs schätzen:
- Verwenden Sie für Largest Contentful Paint (LCP) die Differenz zwischen dem Zeitstempel des
pageshow-Ereignisses und dem Zeitstempel des nächsten gerenderten Frames, da alle Elemente im Frame gleichzeitig gerendert werden. Bei einer bfcache-Wiederherstellung sind LCP und FCP identisch. - Verwenden Sie für Interaction to Next Paint (INP) weiterhin Ihren vorhandenen Performance Observer, setzen Sie den aktuellen INP-Wert jedoch auf 0 zurück.
- Verwenden Sie für Cumulative Layout Shift (CLS) weiterhin Ihren vorhandenen Performance Observer, setzen Sie den aktuellen CLS-Wert aber auf 0 zurück.
Weitere Informationen dazu, wie sich der Bfcache auf die einzelnen Messwerte auswirkt, finden Sie auf den Seiten mit den Leitfäden zu den einzelnen Core Web Vitals. Ein konkretes Beispiel für die Implementierung von bfcache-Versionen dieser Messwerte finden Sie im PR, in dem sie der web-vitals-JS-Bibliothek hinzugefügt werden.
Die JavaScript-Bibliothek web-vitals unterstützt bfcache-Wiederherstellungen in den von ihr gemeldeten Messwerten.
Zusätzliche Ressourcen
- Firefox-Caching (bfcache in Firefox)
- Seitencache (bfcache in Safari)
- Back-Forward-Cache: Web-Exposed-Verhalten (bfcache-Unterschiede zwischen Browsern)
- bfcache-Tester (testen, wie sich verschiedene APIs und Ereignisse auf den bfcache in Browsern auswirken)
- Performance Game Changer: Browser Back/Forward Cache (a case study from Smashing Magazine showing dramatic Core Web Vitals improvements by enabling bfcache)