Back/Forward Cache: What It Is and How to Implement It

TL;DR

Back/Forward Cache is a browser feature that stores a webpage when users go back or forward to make the cached content load instantly when users navigate to it. To keep pages eligible, avoid the legacy unload event, keep Cache-Control: no-store to pages that really need it, and close open connections before users navigate away.

Imagine this…

A user is browsing your website. They go to your product page. Then to your pricing page. Then back to your product page as they forgot to check if you offer that specific feature. Finally, they navigate forward to your pricing page and finish their order. 

As it turns out, it’s a pretty common scenario. 

Chrome usage data shows that 1 in 10 (10%) navigations on desktop and 1 in 5 (20%) on mobile are either back or forward.

Truly spectacular numbers. 

But…

The more important thing is – how can you guarantee that after navigating back and forward to your pages, they load immediately? 

Enter back/forward cache (or bfcache).

In the following lines, you will learn everything about bfcache and how to implement it to improve speed and perceived performance.

Spoiler alert: it’s easier than you think. 

What is the back/forward cache?

Bfcache is a feature that allows browsers to create and store a snapshot of an already visited web page in their in-memory. So the next time a visitor navigates back or forward to it, the browser can display it immediately.

The whole behind-the-scene process looks like this…

When a visitor requests to load a specific page, the browser goes through the following process:

  1. Establishes a connection with the server
  2. Downloads and parses the information
  3. Constructs the Document Object Model (DOM) and CSS Object Model (CSSOM)
  4. Renders the content
  5. Makes the page interactive
Browser loading a web page

If the back/forward cache isn’t enabled for the specific page, it means that every time you leave it and then navigate back to it, the browser will have to go through the whole 5-step process. 

And that takes time. 

On the contrary, with bfcache enabled, the browser “freezes” the page with all of its resources, so the next time you re-visit it, the browser won’t need to waste time rebuilding and will be able to load it instantly. 

The following Addy Osmani’s video illustrates best how fast a web page loads with and without bfcache:

As you can see from the video, the loading time is almost non-existent. On top of that, bfcache will reduce your visitors’ data usage as they won’t have to re-download the same resources repeatedly. 

And while all of these benefits sound incredible, a certain question might still bother you:

I already have an HTTP cache set up for my website. Do I need bfcache as well? 

Here’s the answer…

What is the Difference between bfcache and HTTP cache?

Put simply, bfcache is a snapshot of the entire page stored in-memory (including the JavaScript heap), whereas the HTTP cache includes only the previously requested resources. 

And as Google claims:

“…it’s quite rare that all requests required to load a page can be fulfilled from the HTTP cache…”

Not all resources are allowed to be cached in the HTTP Cache. For instance, some sites don’t cache the HTML document itself, but only the resources. As a result, every time a visitor loads a specific page, the browser needs to re-download the document. 

Another reason back/forward cache can be faster is the difference between in-memory and disk cache. 

It’s true that loading resources from the disk cache (HTTP cache) could be much faster than requesting them over the network. But there’s an extra boost from not even having to read them from disk and fetching the entire page directly from the browser’s in-memory. 

What browsers support the back/forward cache?

All of them – Chrome, Safari, Firefox, Opera, and Edge:

Bfcache browser support

The truth is back/forward cache isn’t a new concept. Safari added support for this feature back in 2009. Firefox has supported it since version 1.5.

Edge and Chrome were the latest to join the party, with the former introducing bfcache in 2020, while the latter did it in Chrome 96 (late 2021). 

Now that you know that all major browsers support it let’s see how you can check if your page is served from the bfcache. 

How can I check if my site can be served from the back/forward cache?

The best thing about back/forward cache is that it just works in the majority of cases because browsers automatically do all the work for you.

In some cases, however, your pages will not be restored by the bfcache. 

The easiest way to check if everything works correctly is to run a PageSpeed Insights audit. 

Using Google PageSpeed Insights

Since the release of Lighthouse v10, there’s been a new PSI audit called “Page prevented back/forward cache restoration.” 

The audit will fail if the page you tested cannot be restored from bfcache for any reason. Clicking on the warning, a drop-down menu will open, and you’ll see a list with reasons and the frame(s) that caused the issue.

Failure reasons are separated into three categories:

  • Actionable: You can fix these issues to enable caching.
  • Pending Support: Chrome doesn’t support these features yet, so they prevent caching. However, once supported, Chrome removes these limitations.
  • Not Actionable: You can’t fix these issues on this page. Something that is outside the page’s control prevents caching.
Page prevented back/forward cache restoration warning

Using Chrome DevTools

Another option is to use Chrome’s Developer Tools, following these steps:

1. Open Chrome DevTools on the page you want to test:

2. Navigate to Application > Cache > Back/forward cache:

3. Click Test back/forward cache

Click Test back/forward cache

If bfcache works on your page, you’ll see this message:

Page eligible for bfcache

If not, you will see a list of issues:

Page ineligible for bfcache

Now that you know how to test it, let’s see how you can optimize your pages for bfcache and fix PSI’s warning. 

How can you see why a page failed bfcache in the field?

DevTools and PageSpeed Insights test one page in the lab. To see why real visitors’ navigations miss the bfcache, use the NotRestoredReasons API. It’s part of PerformanceNavigationTiming, and it reports the reasons a page wasn’t restored from bfcache for actual navigations, so you can catch blockers that only show up with real traffic. Chrome also breaks its Core Web Vitals data down by navigation type in the Chrome User Experience Report (CrUX), which lets you see how many of your back and forward navigations actually used the bfcache without instrumenting anything yourself.

How to fix the “Page prevented back/forward cache restoration” warning in PageSpeed Insights

Even if you don’t see the warning, meaning your page is eligible for bfcache, it’s good to know that it won’t stay there indefinitely.

That’s why it’s worth knowing how to optimize for back/forward cache.

Here are some best practices you can use to make it as likely as possible that browsers bfcache your pages:

1. Avoid using the unload event 

The most surefire way to optimize for bfcache is to avoid using the unload event at all costs. 

The unload event fires when the user navigates away from the page (by clicking on a link, submitting a form, closing the browser window, etc.).

On desktop, Chrome and Firefox consider a page ineligible for bfcache if it uses the unload event. Safari, on the other hand, will cache some pages that fire the unload event listener, but to reduce potential breakage, it will not run it when a user is navigating away.

On mobile, Chrome and Safari will cache a page that uses the event, but Firefox won’t. 

In general, avoid using the unload event and instead go for the pagehide event. Otherwise, you’re risking slowing down your site, and your code won’t even run most of the time in Chrome and Safari. 

If your site doesn’t use unload at all, you can lock that in with a Permissions Policy so a third-party script or browser extension can’t add one and quietly make your pages ineligible. Add this HTTP response header:

Permissions-Policy: unload=()

Chrome is also in the process of deprecating the unload event, so moving off it now is future-proofing as much as a bfcache fix

2. Be careful with adding beforeunload listeners

The beforeunload event no longer makes your pages ineligible for bfcache in modern browsers — but it used to, and it’s still unreliable, so it’s best avoided unless you genuinely need it.

However, there are legitimate use cases for the beforeunload event, unlike the unload event. One example is when you must caution the user about losing unsaved changes if they exit the page. It’s advisable to attach beforeunload event listeners only when there are unsaved changes and to remove them promptly after saving those changes.

3. Use Cache-Control: no-store only with information-sensitive pages

If a page contains sensitive information and caching is inappropriate, then Cache-Control: no-store should be used to prevent it from being eligible for bfcache. On the other hand, if a page doesn’t contain sensitive information and always requires up-to-date content, Cache-Control: no-cache or Cache-Control: max-age=0 can be used. These directives prompt the browser to revalidate the content before serving it and don’t impact a page’s eligibility for bfcache.

Important: Chrome now allows pages with Cache-Control: no-store into the back/forward cache when it’s safe to do so — the rollout reached 100% of page loads in March–April 2025. Chrome evicts such a page if a cookie or other authorization changes, if it uses WebSocket, WebTransport, or WebRTC, or if a fetch or XHR request returns Cache-Control: no-store. Their bfcache timeout is 3 minutes rather than the usual 10. Other browsers can still block bfcache on no-store pages, so keep no-store for pages that genuinely hold sensitive data.

4. Update sensitive data after bfcache restore

The bfcache isn’t supposed to work for pages that contain sensitive data. For instance, when a user signs out of a website on a public computer, the next user shouldn’t be able to sign back in just by hitting the back button. 

To achieve that, it’s a good practice to update the page after a pageshow event if event.persisted is true.

Here’s a code from web.dev you can use:

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

5. Avoid window.opener reference

Whenever possible, use rel=”noopener” instead of window.opener references (this is now the default in all modern browsers). The opened window or the opener won’t be eligible for bfcache if your site opens windows and controls them through window.postMessage().

Always close connections and disconnect observers during the pagehide and freeze event

6. Always close connections and disconnect observers during the pagehide and freeze event

When the page is stored in the bfcache, all JavaScript tasks are paused and resumed as soon as it is taken out of the cache.

If these tasks only access APIs isolated to the current page, there won’t be any problems. 

However, if these tasks are connected to APIs that are also accessible from other pages in the same origin, then they may prevent code in other tabs from running properly.

If that’s the case, some browsers will not put a page in bfcache in the following scenarios:

The best thing you can do is to permanently close connections and remove or disconnect observers during pagehide or freeze events if your page uses any of these APIs. By doing this, the browser can cache the page without worrying about other open tabs being affected.

Key takeaways

For something handled by browsers, we’ve covered a lot of information. 

So here are the key takeaways from this article:

  • Bfcache lets browsers store a snapshot of an already-visited page in memory, so back and forward navigation loads instantly.
  • Being served from the bfcache reduces data usage and improves perceived performance, Core Web Vitals, and user experience.
  • The difference from the HTTP cache: bfcache stores a snapshot of the whole page, while the HTTP cache only stores the resources you requested before.
  • All major browsers support back/forward cache.
  • Check whether a page is eligible using PageSpeed Insights or Chrome DevTools, and see why real navigations fail using the NotRestoredReasons API and CrUX.
  • To optimize your pages and clear the “Page prevented back/forward cache restoration” warning:
    • Avoid the unload event, and lock it out with Permissions-Policy: unload=()
    • Add beforeunload listeners only when you actually need them
    • Keep Cache-Control: no-store to pages with sensitive data (Chrome now bfcaches no-store pages when it’s safe, but other browsers may not)
    • Avoid window.opener references
    • Close connections and disconnect observers during the pagehide and freeze events

As always, don’t forget to test. Back/forward cache is a great feature, but remember that not every page should be eligible for it. Your visitors’ experience should always be a first priority.

Niko Kaleev

By Niko Kaleev

User Experience Content Expert

Niko has 5+ years of experience turning those “it’s too technical for me” topics into “I can’t believe I get it” content pieces. He specializes in dissecting nuanced topics like Core Web Vitals, web performance metrics, and site speed optimization techniques. When he’s taking a breather from researching his next content piece, you’ll find him deep into the latest performance news.