Reference guide · performance · Published 2026-08-16 · 3 min read
Back/forward cache (bfcache) and page restore
Back/forward cache restores pages instantly on back and forward. Learn eligibility rules and how to keep pages bfcache-friendly.
- ·What bfcache does
- ·The eligibility rules
- ·Measuring and testing
What bfcache does
The back/forward cache (bfcache) is a browser optimisation that stores a snapshot of a page the moment the user navigates away, so that going back or forward restores it instantly from memory instead of loading it again over the network. When the cache hits, the page appears immediately with its DOM, scripts, form state and scroll position intact, which makes a large share of navigation effectively instant. Roughly one in ten desktop navigations and one in five mobile navigations are back or forward, so the feature has a large influence over the field experience.
Every major engine ships a back/forward cache, including Chrome (since version 96), Firefox and Safari, and the Chromium-based browsers inherit Chrome's implementation. The browser restores the cached page without re-running the page load, so it behaves like a freshly resumed page rather than a reload, and it re-appears as the user left it.
The eligibility rules
A page is only cached if it is eligible, and each engine applies its own checks. Several common features disqualify a page:
- An
unloadevent listener. Chrome and Firefox treat a page that addsunloadas ineligible for bfcache on desktop, because it implies the page relies on code that may not run when the page is restored. Use thepagehideevent instead, which fires both when a page unloads and when it is put into the cache. - Open network or storage connections. Pages with an open WebSocket or WebRTC connection, in-progress
fetch()or XMLHttpRequest, or a pending IndexedDB transaction can be blocked from caching. Cache-Control: no-storeon the main resource. Historically this blocked bfcache in all engines. Chrome since 2025 allows no-store pages under limited conditions (evicting the cached copy if cookies change and declaring them ineligible later), but other browsers still treat no-store as a blocker, so reserve it for genuinely sensitive pages.- Broad
Cache-Controland auth state changes. If cookies or authentication state change while a page is frozen, the cached copy is evicted for safety.
These are worth knowing because the fix for a page that never restores is usually not a cache header but the removal of an unnecessary unload handler or the closing of an open connection.
Measuring and testing
The web.dev bfcache guidance and Chrome DevTools provide a "Test back/forward cache" tool that navigates the page away and back to report whether it was restored, and on Chrome the NotRestoredReasons API exposes why a page was excluded. A Chrome pass is necessary but not sufficient: Firefox and Safari apply their own eligibility rules, so a page that restores in one engine may still reload in another.
To detect a restore at runtime, use the pageshow event and read event.persisted, which is true when the page was served from the cache:
window.addEventListener("pageshow", (event) => {
if (event.persisted) {
console.log("Restored from back/forward cache");
}
});
Reasoning about bfcache belongs alongside the wider Core Web Vitals picture: it is not a separate metric but a behaviour that makes a class of navigation effectively free. It complements the service worker cache, which accelerates fresh loads, while bfcache accelerates revisits within a session. After a change that affects these handlers, re-run the bfcache test as part of the regular web performance audit, because an otherwise-fast page that never restores leaves the fastest navigations on the table.