Optimieren Sie Ihre Seiten für sofortige Ladevorgänge, wenn Sie die Browserschaltflächen „Zurück“ und „Vorwärts“ verwenden.
Der Back-Forward-Cache (oder bfcache) ist eine Browseroptimierung, die eine sofortige Zurück- und Vorwärtsnavigation ermöglicht. Sie verbessert das Surfen im Web für Nutzer, insbesondere solche mit langsamen Netzwerken oder Geräten.
Als Webentwickler sollten Sie unbedingt wissen, wie Sie Ihre Seiten in allen Browsern für den bfcache optimieren, damit Ihre Nutzer von diesen Vorteilen profitieren können.
Browserkompatibilität
bfcache wird seit vielen Jahren sowohl in Firefox als auch in Safari auf Computern und Mobilgeräten unterstützt.
Ab Version 86 wurde der bfcache für einen kleinen Prozentsatz der Nutzer in Chrome für websiteübergreifende Navigationen unter Android aktiviert. In nachfolgenden Releases wurde nach und nach zusätzliche Unterstützung eingeführt. Seit Version 96 ist bfcache für alle Chrome-Nutzer auf Computern und Mobilgeräten aktiviert.
bfcache-Grundlagen
bfcache ist ein speicherinterner Cache, der einen vollständigen Snapshot einer Seite (einschließlich des JavaScript-Heaps) speichert, während der Nutzer die Seite verlässt. Da die gesamte Seite im Arbeitsspeicher ist, kann der Browser sie schnell und einfach wiederherstellen, falls der Nutzer später zurückkehren möchte.
Wie oft haben Sie eine Website besucht und auf einen Link geklickt, um zu einer anderen Seite zu gelangen, und haben dann auf die Schaltfläche „Zurück“ geklickt? In diesem Moment kann bfcache einen großen Einfluss darauf haben, wie schnell die vorherige Seite geladen wird:
Ohne bfcache aktiviert | Es wird eine neue Anfrage zum Laden der vorherigen Seite initiiert. 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 noch einmal ausführen. |
Mit aktiviertem bfcache | Die vorherige Seite wird im Prinzip sofort geladen, da die gesamte Seite aus dem Speicher wiederhergestellt werden kann, ohne zum Netzwerk wechseln zu müssen. |
Sehen Sie sich dieses Video an, in dem gezeigt wird, wie schnell bfcache bei der Navigation genutzt werden kann:
Im obigen Video ist das Beispiel mit bfcache etwas schneller als das ohne.
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 Computern und 1 von 5 Navigationen auf Mobilgeräten entweder zurück oder vorwärts erfolgen. Mit aktiviertem bfcache können Browser die Datenübertragung und die tägliche Ladezeit für Milliarden von Webseiten eliminieren.
Funktionsweise des „Cache“
Der von bfcache verwendete „Cache“ unterscheidet sich vom HTTP-Cache, der auch zur Beschleunigung wiederholter Navigationen nützlich ist. Der 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 gesendete Anfragen enthält. Da es recht selten ist, dass alle zum Laden einer Seite erforderlichen Anfragen über den HTTP-Cache ausgeführt werden können, sind wiederholte Besuche mit bfcache-Wiederherstellungen immer schneller als selbst die besten, nicht vom bfcache optimierten Navigationen.
Das Erstellen eines Snapshots einer Seite im Arbeitsspeicher ist jedoch etwas kompliziert im Hinblick darauf, wie sich in Bearbeitung befindlichen Code am besten beibehalten lassen. Wie werden beispielsweise setTimeout()
-Aufrufe verarbeitet, bei denen das Zeitlimit erreicht wird, während sich die Seite im bfcache befindet?
Die Antwort ist, dass die Browser die Ausführung aller ausstehenden Timer oder ungelösten Versprechen – im Grunde alle ausstehenden Aufgaben in den JavaScript-Aufgabenwarteschlangen – unterbrechen und Verarbeitungsaufgaben fortsetzen, wenn (oder falls) die Seite aus dem bfcache wiederhergestellt wird.
In einigen Fällen ist dies ein relativ geringes Risiko (z. B. bei Zeitüberschreitungen oder Versprechen), in anderen Fällen kann es zu sehr verwirrendem oder unerwartetem Verhalten führen. Wenn der Browser beispielsweise eine Aufgabe pausiert, die im Rahmen einer IndexedDB-Transaktion erforderlich ist, kann sich dies auf andere geöffnete Tabs im selben Ursprung auswirken, da dieselbe IndexedDB-Datenbanken von mehreren Tabs gleichzeitig aufgerufen werden können. Daher versuchen Browser normalerweise nicht, Seiten während einer IndexedDB-Transaktion im Cache zu speichern oder APIs zu verwenden, die andere Seiten beeinflussen könnten.
Weitere Informationen dazu, wie sich verschiedene API-Nutzung auf die bfcache-Berechtigung einer Seite auswirkt, finden Sie unten im Abschnitt Seiten für bfcache optimieren.
bfcache und Single Page Apps (SPA)
Der bfcache funktioniert mit browserverwalteten Navigationen. Daher funktioniert es nicht mit den sogenannten „weichen Navigationen“ innerhalb einer SPA, aber eines der wichtigsten Verkaufsargumente ist, dass diese Arten von Navigationen ohnehin schnell sein sollten. Der bfcache kann jedoch auf jeden Fall hilfreich sein, wenn Sie zu einer SPA zurückwechseln, anstatt die App von Anfang an komplett neu zu initialisieren.
APIs zur Beobachtung des bfcache
Obwohl bfcache eine Optimierung ist, die Browser automatisch vornehmen, ist es für Entwickler trotzdem wichtig, dass sie wissen, wann das passiert, damit sie ihre Seiten dafür optimieren und alle Messwerte oder Leistungsmessungen entsprechend anpassen können.
Die primären Ereignisse, die zum Beobachten des bfcache verwendet werden, sind die Seitenübergangsereignisse pageshow
und pagehide
. Diese gibt es schon, so lange wie „bfcache“ es schon gibt und die in so ziemlich allen derzeit verwendeten Browsern unterstützt werden.
Die neueren Ereignisse im Seitenlebenszyklus – freeze
und resume
– werden ebenfalls gesendet, wenn Seiten in den bfcache aufgenommen oder daraus entfernt werden, sowie in einigen anderen Situationen. z. B. wenn ein Tab im Hintergrund eingefroren wird, um die CPU-Auslastung zu minimieren. Hinweis: Ereignisse im Seitenlebenszyklus werden derzeit nur in Chromium-basierten Browsern unterstützt.
Beobachten, wenn eine Seite aus dem bfcache wiederhergestellt wird
Das pageshow
-Ereignis wird direkt nach dem load
-Ereignis ausgelöst, wenn die Seite anfangs geladen wird, und jedes Mal, wenn die Seite aus dem bfcache wiederhergestellt wird. Das Ereignis pageshow
hat das Attribut persisted
, das true
ist, wenn die Seite aus dem bfcache wiederhergestellt wurde, und false
, wenn nicht. Mit dem Attribut 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 resume
-Ereignis auch ausgelöst, wenn Seiten aus dem bfcache wiederhergestellt werden (direkt vor dem pageshow
-Ereignis). Es wird jedoch auch ausgelöst, wenn ein Nutzer einen gesperrten Hintergrund-Tab besucht.
Wenn Sie den Status einer Seite aktualisieren möchten, nachdem sie eingefroren wurde (was Seiten im bfcache umfasst), können Sie das Ereignis resume
verwenden. Wenn Sie jedoch die bfcache-Trefferquote Ihrer Website messen möchten, müssen Sie das Ereignis pageshow
verwenden. In einigen Fällen müssen Sie
möglicherweise beide verwenden.
Beobachten, wenn eine Seite in den bfcache eingeht
Das pagehide
-Ereignis ist das Gegenstück zum pageshow
-Ereignis. Das Ereignis pageshow
wird ausgelöst, wenn eine Seite entweder normal geladen oder aus dem bfcache wiederhergestellt wird.
Das pagehide
-Ereignis wird ausgelöst, wenn die Seite entweder normal entladen wird oder wenn der Browser versucht, sie in den bfcache zu speichern.
Das pagehide
-Ereignis hat auch ein persisted
-Attribut. Wenn es false
lautet, können Sie sicher sein, dass eine Seite nicht in den bfcache gelangen wird. Wenn das Attribut persisted
jedoch den Wert true
hat, bedeutet das keine Garantie dafür, dass eine Seite im Cache gespeichert wird.
Das bedeutet, dass der Browser die Seite intends, es jedoch Faktoren geben kann, die das Speichern der Seite nicht mö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 sofort nach dem pagehide
-Ereignis ausgelöst, wenn die Eigenschaft persisted
des Ereignisses true
ist. Dies bedeutet jedoch nur, dass der Browser intends. Es kann sein, dass er aus verschiedenen Gründen, die im Folgenden beschrieben werden, verworfen werden muss.
Seiten für bfcache optimieren
Nicht alle Seiten werden im bfcache gespeichert, und selbst wenn eine Seite dort gespeichert wird, bleibt sie nicht auf unbestimmte Zeit dort. Es ist wichtig, dass Entwickler verstehen, wodurch Seiten für bfcache infrage kommen (und nicht geeignet) werden, um ihre Cache-Trefferraten zu maximieren.
In den folgenden Abschnitten werden die Best Practices beschrieben, die es so wahrscheinlich wie möglich machen, dass der Browser Ihre Seiten im Cache speichern kann.
unload
-Ereignis nie verwenden
Die wichtigste Methode zur Optimierung des bfcache-Werts in allen Browsern besteht darin, nie das unload
-Ereignis zu verwenden. Niemals!
Das unload
-Ereignis stellt für Browser Probleme dar, da es älter als bfcache ist und viele Seiten im Internet unter der (vernünftigen) Annahme, dass eine Seite nicht mehr existiert, nachdem das unload
-Ereignis ausgelöst wurde. Das stellt eine Herausforderung dar, da viele dieser Seiten auch mit der Annahme erstellt wurden, dass das Ereignis unload
jedes Mal ausgelöst wird, wenn ein Nutzer die Seite verlässt, was nicht mehr der Fall ist (und schon lange nicht mehr der Fall ist).
Browser stehen also vor einem Dilemma. Sie müssen zwischen etwas wählen, das die Nutzererfahrung verbessern kann, aber sie könnten auch Gefahr laufen, die Seite zu stören.
Auf dem Computer haben Chrome und Firefox sich dazu entschieden, Seiten nicht für den bfcache zu verwenden, wenn sie einen unload
-Listener hinzufügen. Dies ist zwar weniger riskant, erfüllt aber viele Seiten nicht. Safari versucht, einige Seiten mit einem unload
-Ereignis-Listener im Cache zu speichern. Um potenzielle Fehler zu vermeiden, wird jedoch das unload
-Ereignis nicht ausgeführt, wenn ein Nutzer die Seite verlässt. Dadurch wird das Ereignis sehr unzuverlässig.
Auf Mobilgeräten versuchen Chrome und Safari, Seiten mit einem unload
-Ereignis-Listener im Cache zu speichern. Das liegt daran, dass das unload
-Ereignis auf Mobilgeräten immer extrem unzuverlässig war. Das liegt daran, dass das Risiko von Fehlern geringer ist. Firefox behandelt Seiten, die unload
verwenden, als nicht für den bfcache geeignet. Eine Ausnahme bildet iOS. Hier müssen alle Browser das WebKit-Rendering-Modul verwenden. Daher verhält es sich wie Safari.
Verwenden Sie statt des unload
-Ereignisses das pagehide
-Ereignis. Das Ereignis pagehide
wird in allen Fällen ausgelöst, in denen derzeit das Ereignis unload
ausgelöst wird, sowie auch, wenn eine Seite in den bfcache aufgenommen wird.
Tatsächlich gibt es in Lighthouse eine no-unload-listeners
-Prüfung, bei der Entwickler gewarnt werden, wenn JavaScript auf ihren Seiten (auch das von Drittanbieterbibliotheken) einen unload
-Event-Listener hinzufügt.
Aufgrund der Unzuverlässigkeit und der Leistungsbeeinträchtigung für den bfcache wird in Chrome das unload
-Ereignis eingestellt.
Verwende die Berechtigungsrichtlinie, um zu verhindern, dass Unload-Handler auf einer Seite verwendet werden
Websites, die keine unload
-Event-Handler verwenden, können mithilfe einer Berechtigungsrichtlinie von Chrome 115 dafür sorgen, dass diese nicht hinzugefügt werden.
Permission-Policy: unload()
Dadurch wird verhindert, dass Dritte oder Erweiterungen die Website durch Hinzufügen von Unload-Handlern verlangsamen, wodurch die Website nicht mehr für den bfcache infrage kommt.
beforeunload
-Listener nur bedingt hinzufügen
Das beforeunload
-Ereignis führt nicht dazu, dass deine Seiten im bfcache von modernen Browsern nicht für den bfcache infrage kommen. Bisher war das aber der Fall und es ist immer noch unzuverlässig. Verwende es also nur, wenn es absolut notwendig ist.
Im Gegensatz zum unload
-Ereignis kann beforeunload
jedoch legitim verwendet werden. Wenn Sie beispielsweise den Nutzer warnen möchten, dass er nicht gespeicherte Änderungen hat, gehen diese verloren, wenn er die Seite verlässt. In diesem Fall wird empfohlen, beforeunload
-Listener nur dann hinzuzufügen, wenn ein Nutzer nicht gespeicherte Änderungen hat, und sie dann 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?'; } });
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); });
Verwendung von Cache-Control: no-store
minimieren
Cache-Control: no-store
ist ein HTTP-Header, den Webserver für Antworten festlegen können. Er weist den Browser an, die Antwort nicht in einem HTTP-Cache zu speichern. Er sollte für Ressourcen verwendet werden, die vertrauliche Nutzerdaten enthalten, z. B. für Seiten, für die eine Anmeldung erforderlich ist.
Obwohl „bfcache“ kein HTTP-Cache ist, haben Browser sich bisher entschieden, die Seite nicht im bfcache zu speichern, wenn Cache-Control: no-store
auf der Seitenressource selbst (im Gegensatz zu einer Unterressource) festgelegt ist. Wir arbeiten daran, dieses Verhalten in Chrome auf datenschutzfreundliche Weise zu ändern. Derzeit kommen jedoch Seiten, für die Cache-Control: no-store
verwendet wird, nicht für den bfcache infrage.
Da Cache-Control: no-store
die Eignung einer Seite für den bfcache einschränkt, sollte sie nur auf Seiten festgelegt werden, die vertrauliche Informationen enthalten, bei denen ein Caching jeglicher Art nie angemessen ist.
Für Seiten, auf denen immer die aktuellen Inhalte angezeigt werden sollen und die keine vertraulichen Informationen enthalten, verwende Cache-Control: no-cache
oder Cache-Control: max-age=0
. Diese Anweisungen weisen den Browser an, den Inhalt vor der Bereitstellung erneut zu validieren, und wirken sich nicht auf die bfcache-Eignung einer Seite aus.
Wenn eine Seite aus dem bfcache wiederhergestellt wird, wird sie aus dem Arbeitsspeicher wiederhergestellt, nicht aus dem HTTP-Cache. Anweisungen wie Cache-Control: no-cache
oder Cache-Control: max-age=0
werden daher nicht berücksichtigt und es findet keine Neuvalidierung statt, bevor der Inhalt dem Nutzer angezeigt wird.
Da die Wiederherstellung mit dem bfcache aber trotzdem von Vorteil ist, ist es unwahrscheinlich, dass die Inhalte veraltet sind, da Seiten nicht sehr lange im bfcache verbleiben. Falls sich Ihre Inhalte jedoch minutengenau ändern, können Sie Aktualisierungen mit dem pageshow
-Ereignis abrufen, wie im nächsten Abschnitt beschrieben.
Veraltete oder sensible Daten nach der bfcache-Wiederherstellung aktualisieren
Wenn Ihre Website den Nutzerstatus behält – insbesondere vertrauliche Nutzerdaten –, müssen diese Daten nach dem Wiederherstellen einer Seite aus dem bfcache aktualisiert oder gelöscht werden.
Wenn ein Nutzer beispielsweise zu einer Zahlungsseite geht und dann seinen Einkaufswagen aktualisiert, könnten über eine Zurück-Navigation veraltete Informationen angezeigt werden, wenn eine veraltete Seite aus dem bfcache wiederhergestellt wird.
Ein weiteres, kritischeres Beispiel wäre, wenn sich ein Nutzer auf einem öffentlichen Computer von einer Website abmeldet und der nächste Nutzer auf die Schaltfläche „Zurück“ klickt. Dadurch könnten private Daten preisgegeben werden, von denen der Nutzer bei der Abmeldung angenommen hat, dass sie gelöscht wurden.
Um solche Situationen zu vermeiden, solltest du die Seite immer nach einem pageshow
-Ereignis aktualisieren, wenn event.persisted
den Wert true
hat:
window.addEventListener('pageshow', (event) => {
if (event.persisted) {
// Do any checks and updates to the page
}
});
Im Idealfall aktualisieren Sie den vorhandenen Inhalt. Bei einigen Änderungen kann ein vollständiges Aktualisieren erzwungen werden. Mit dem folgenden Code wird geprüft, ob im Ereignis pageshow
ein websitespezifisches Cookie vorhanden ist. Wird kein Cookie gefunden, wird der Code aktualisiert:
window.addEventListener('pageshow', (event) => {
if (event.persisted && !document.cookie.match(/my-cookie/)) {
// Force a reload if the user has logged out.
location.reload();
}
});
Eine Aktualisierung hat den Vorteil, dass der Verlauf erhalten bleibt (um Vorwärtsnavigationen zu ermöglichen), aber eine Weiterleitung kann in einigen Fällen geeigneter sein.
Wiederherstellung von Anzeigen und bfcache
Es kann verlockend sein, auf die Verwendung von bfcache zu verzichten, um in jeder Vorwärts-/Vorwärtsnavigation einen neuen Satz von Anzeigen auszuliefern. Allerdings wirkt sich dies positiv auf die Leistung aus, es ist jedoch fraglich, ob ein solches Verhalten zu einer höheren Anzeigeninteraktion führt. Die Nutzer haben möglicherweise eine Anzeige bemerkt, auf die sie zurückkehren sollten, indem sie sie neu laden, anstatt sie aus dem bfcache wiederherzustellen. Dieses Szenario sollte möglichst mit einem A/B-Test getestet werden, bevor Annahmen getroffen werden.
Bei Websites, die Anzeigen nach der Wiederherstellung mit dem bfcache aktualisieren möchten, kann die Aktualisierung nur der Anzeigen für das Ereignis pageshow
erfolgen, wenn event.persisted
den Wert true
hat, um dies ohne Auswirkungen auf die Seitenleistung zu tun. Wenden Sie sich an Ihren Anzeigenanbieter. Hier ist ein Beispiel dafür, wie Sie das Google Publisher-Tag verwenden können.
window.opener
-Verweise vermeiden
Wenn eine Seite in älteren Browsern mit window.open()
über einen Link mit target=_blank
(ohne rel="noopener"
) geöffnet wurde, verweist die öffnende Seite auf das Fensterobjekt der geöffneten Seite.
Eine Seite mit einem window.opener
-Verweis, der nicht null ist, stellt ein Sicherheitsrisiko dar und kann nicht sicher in den bfcache verschoben werden, da dadurch alle Seiten beschädigt werden, die darauf zugreifen könnten.
Daher sollte das Erstellen von window.opener
-Referenzen vermieden werden. Dazu können Sie nach Möglichkeit rel="noopener"
verwenden. Hinweis: Diese Option ist jetzt in allen modernen Browsern die Standardeinstellung. Wenn für Ihre Website das Öffnen eines Fensters und dessen Steuerung über window.postMessage()
oder das direkte Verweisen auf das Fensterobjekt erforderlich ist, kommen weder das geöffnete Fenster noch das Öffnender für den bfcache infrage.
Immer offene Verbindungen schließen, bevor der Nutzer die Seite verlässt
Wie bereits erwähnt, werden beim Speichern einer Seite in den bfcache alle geplanten JavaScript-Aufgaben pausiert und fortgesetzt, sobald die Seite aus dem Cache genommen wird.
Wenn diese geplanten JavaScript-Aufgaben nur auf DOM APIs oder andere APIs zugreifen, die nur auf der aktuellen Seite isoliert sind, wird das Pausieren dieser Aufgaben, während die Seite nicht für den Nutzer nicht sichtbar ist, keine Probleme verursachen.
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 usw.), 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 Szenarien nicht, eine Seite in den bfcache zu speichern:
- Seiten mit einer offenen IndexedDB-Verbindung
- Seiten mit fetch() oder XMLHttpRequest
- Seiten mit einer offenen WebSocket- oder WebRTC-Verbindung
Wenn Ihre Seite eine dieser APIs verwendet, ist es am besten, Verbindungen immer zu trennen und Beobachter während des pagehide
- oder freeze
-Ereignisses zu entfernen oder zu trennen. Auf diese Weise kann der Browser die Seite sicher im Cache speichern, ohne dass andere geöffnete Tabs dadurch beeinträchtigt werden.
Wenn die Seite dann aus dem bfcache wiederhergestellt wird, können Sie diese APIs noch einmal öffnen oder eine Verbindung zu ihnen herstellen (im Ereignis pageshow
oder resume
).
Das folgende Beispiel zeigt, wie Sie bei Verwendung von IndexedDB dafür sorgen können, dass Ihre Seiten für den bfcache infrage kommen, indem Sie eine offene Verbindung im Event-Listener pagehide
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 is leaving.
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 kannst du deine Seiten testen, um zu prüfen, ob sie für bfcache optimiert sind, und Probleme identifizieren, die möglicherweise verhindern, dass sie verwendet werden.
Wenn Sie eine bestimmte Seite testen möchten, rufen Sie sie in Chrome auf und gehen Sie dann in den Entwicklertools zu Anwendung > Back-Forward-Cache. Klicken Sie als Nächstes auf die Schaltfläche Run Test (Test ausführen). Die Entwicklertools versuchen dann, die Seite zu verlassen und wieder zurückzukehren, um festzustellen, ob die Seite aus dem bfcache wiederhergestellt werden kann.
Wenn der Vorgang erfolgreich war, wird im Steuerfeld „Aus dem Back-Forward-Cache wiederhergestellt“ angezeigt:
Wenn der Vorgang nicht erfolgreich war, wird im Steuerfeld angezeigt, dass die Seite nicht wiederhergestellt wurde. Außerdem wird der Grund dafür aufgeführt.
Wenn der Grund etwas ist, das Sie als Entwickler beheben können, wird das ebenfalls angegeben:
Im Screenshot oben verhindert die Verwendung eines unload
-Event-Listeners, dass die Seite den bfcache verwenden kann. Sie können das Problem beheben, indem Sie von unload
zu pagehide
wechseln:
window.addEventListener('unload', ...);
window.addEventListener('pagehide', ...);
In Lighthouse 10.0 wurde außerdem eine bfcache-Prüfung hinzugefügt, die einen ähnlichen Test wie die Entwicklertools durchführt, und auch Gründe dafür angeben, warum die Seite nicht zulässig ist, wenn die Prüfung fehlschlägt. Weitere Informationen finden Sie in der Dokumentation zum bfcache-Audit.
Auswirkungen von bfcache auf Analysen und Leistungsmessungen
Wenn Sie die Besuche auf Ihrer Website mit einem Analysetool erfassen, werden Sie wahrscheinlich einen Rückgang der Gesamtzahl der erfassten Seitenaufrufe feststellen, da Chrome den bfcache weiterhin für mehr Nutzer aktiviert.
Tatsächlich berichten Sie wahrscheinlich bereits zu wenig von Seitenaufrufen von anderen Browsern, in denen bfcache implementiert ist, da die meisten gängigen Analysebibliotheken die bfcache-Wiederherstellung nicht als neue Seitenaufrufe erfassen.
Wenn Sie nicht möchten, dass die Anzahl der Seitenaufrufe sinkt, weil Chrome den bfcache aktiviert hat, können Sie die bfcache-Wiederherstellung als Seitenaufrufe melden (empfohlen). Dazu hören Sie das Ereignis pageshow
und prüfen die Property persisted
.
Das folgende Beispiel zeigt, wie dies mit Google Analytics geht. Die Logik sollte bei anderen Analysetools ähnlich sein:
// 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 nachverfolgen, ob der bfcache verwendet wurde, um Seiten zu identifizieren, die ihn nicht nutzen. Dazu messen Sie den Navigationstyp beim Seitenaufbau:
// 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';
});
}
});
Anhand des Verhältnisses von back_forward
-Navigationen zu back_forward_cache
kann das bfcache-Verhältnis berechnet werden.
Es gibt eine Reihe von Szenarien, die nicht der Websiteinhaber sind, wenn bei der Zurück-/Vorwärtsnavigation der bfcache nicht verwendet wird:
- Der Nutzer schließt den Browser und startet ihn neu.
- Ein Nutzer dupliziert einen Tab.
- Ein Nutzer schließt einen Tab und schließt ihn wieder.
In einigen dieser Fälle wird der ursprüngliche Navigationstyp von einigen Browsern möglicherweise beibehalten und der Typ back_forward
angezeigt, auch wenn es sich nicht um Vorwärts- und Rückwärtsnavigation handelt.
Selbst ohne diese Ausschlüsse wird der bfcache nach einer bestimmten Zeit verworfen, um Arbeitsspeicher zu sparen.
Websiteinhaber sollten also nicht bei allen back_forward
-Navigationen mit einer bfcache-Trefferquote von 100% rechnen. Die Messung des Verhältnisses kann jedoch nützlich sein, um Seiten zu identifizieren, auf denen die Seite selbst die bfcache-Nutzung aufgrund eines hohen Anteils an Zurück- und Vorwärtsnavigation verhindert.
Das Chrome-Team arbeitet an einer NotRestoredReasons
API, um Entwicklern zu zeigen, warum der bfcache nicht verwendet wurde. So können Entwickler besser nachvollziehen, warum der Cache nicht verwendet wurde und ob dies etwas ist, das sie für ihre Websites verbessern können.
Leistungsmessung
bfcache kann sich auch negativ auf die im Feld erfassten Leistungsmesswerte auswirken, insbesondere auf Messwerte, die Seitenladezeiten messen.
Da bfcache-Navigationen eine vorhandene Seite wiederherstellen, anstatt einen neuen Seitenaufbau zu starten, wird die Gesamtzahl der erfassten Seitenladevorgänge bei Aktivierung von bfcache abnehmen. Wichtig ist jedoch, dass die durch bfcache-Wiederherstellungen ersetzten Seitenladevorgänge wahrscheinlich zu den schnellsten Seitenladevorgängen in Ihrem Dataset gehörten. Das liegt daran, dass das Zurück- und Vorwärtsnavigationen per Definition wiederkehrende Besuche sind und wiederholtes Laden von Seiten im Allgemeinen schneller ist als Seitenaufbau bei Erstbesuchern (aufgrund von HTTP-Caching, wie bereits erwähnt).
Das führt zu weniger schnellen Seitenladevorgängen in Ihrem Dataset, was die Verteilung wahrscheinlich langsamer verzerrt – obwohl sich die Leistung für den Nutzer wahrscheinlich verbessert hat.
Es gibt mehrere Möglichkeiten, mit diesem Problem umzugehen. Erstens: Annotieren Sie alle Messwerte zum Seitenaufbau mit dem entsprechenden Navigationstyp: navigate
, reload
, back_forward
oder prerender
. Auf diese Weise können Sie die Leistung innerhalb dieser Navigationstypen weiterhin überwachen, auch wenn die Gesamtverteilung negativ ist. Dieser Ansatz wird für nicht nutzerbezogene Messwerte zum Seitenaufbau wie Time to First Byte (TTFB) empfohlen.
Bei nutzerorientierten Messwerten wie den Core Web Vitals ist es besser, einen Wert zu melden, der das Nutzererlebnis genauer widerspiegelt.
Auswirkungen auf Core Web Vitals
Mit Core Web Vitals wird die Nutzerfreundlichkeit einer Webseite anhand verschiedener Dimensionen gemessen (Ladegeschwindigkeit, Interaktivität, visuelle Stabilität). Da die Bfcache-Wiederherstellungen im Vergleich zum herkömmlichen Seitenaufbau schneller erfolgen, ist es wichtig, dass dies in den Core Web Vitals-Messwerten berücksichtigt wird. Schließlich ist für einen Nutzer nicht wichtig, ob der bfcache aktiviert ist, sondern nur, dass die Navigation schnell war.
Tools wie der Bericht zur Nutzererfahrung in Chrome, die Core Web Vitals-Messwerte erfassen und Berichte dazu erstellen, behandeln bfcache-Wiederherstellungen in ihrem Dataset als separate Seitenbesuche.
Es gibt zwar (noch) keine speziellen Web Performance APIs zum Messen dieser Messwerte nach der Wiederherstellung von bfcache, aber ihre Werte können mit vorhandenen Web-APIs angenähert werden.
- Für Largest Contentful Paint (LCP) können Sie die Differenz zwischen dem Zeitstempel des Ereignisses
pageshow
und dem Zeitstempel des nächsten gezeichneten Frames verwenden, da alle Elemente im Frame gleichzeitig dargestellt werden. Beachten Sie, dass bei einer bfcache-Wiederherstellung der LCP und FCP identisch sind. - Bei First Input Delay (FID) können Sie die Event-Listener (die auch von FID-Polyfill verwendet werden) wieder dem Ereignis
pageshow
hinzufügen und FID als Verzögerung der ersten Eingabe nach der bfcache-Wiederherstellung angeben. - Für Cumulative Layout Shift (CLS) können Sie Ihren vorhandenen Performance Observer weiter verwenden. Dazu müssen Sie lediglich den aktuellen CLS-Wert auf 0 zurücksetzen.
Weitere Informationen dazu, wie sich der bfcache auf die einzelnen Messwerte auswirkt, finden Sie auf den entsprechenden Seiten zu den Core Web Vitals-Messwerten. Ein konkretes Beispiel für die Implementierung von bfcache-Versionen dieser Messwerte im Code finden Sie hier.
Weitere Ressourcen
- Firefox-Caching (bfcache in Firefox)
- Seiten-Cache (bfcache in Safari)
- Back-Forward-Cache: im Web gefährdetes 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 (eine Fallstudie des Smashing Magazine, die deutliche Core Web Vitals-Verbesserungen durch Aktivieren von bfcache zeigt)