skip to content

Back/Forward Cache

A high bfcache hit rate is one of the cheapest speed wins available, and teams are increasingly asked to defend the number. The interview angle here is auditing and measuring it, not reciting the mechanism.

on this pageshow

questions

4

On a shopping site, tapping the browser Back button from a product page to the results list is instant on some sites and looks like a full page load on others. What does the browser's back/forward cache change for the user, and why do performance teams treat that difference as worth chasing?

level: juniorimportance: should knowfreq 42%

answer

  1. restore, not reload
  2. scroll and in-page state survive
  3. no network, no script re-run
  4. back navigation is a big traffic slice
  5. eligibility beats shrinking the bundle

basics

~20 s

A back/forward cache restore returns the previous page instantly — scroll position and in-page state intact, no network requests and no scripts re-run. Back navigations are a sizable share of real traffic, which makes eligibility one of the cheapest perceived-speed wins available.

solid answer

~40 s

When a page is restored from the browser's back/forward cache, the user gets the previous page back essentially instantly: scroll position, form input and in-page JavaScript state are where they left them, and the browser does no network work and re-runs no scripts. A back navigation that misses the cache is an ordinary page load — request, parse, execute, re-fetch data — and usually dumps the user at the top of a list they had scrolled halfway down. Teams care because back navigation is a large minority of real traffic, heavier on mobile, and because eligibility is normally won by removing a blocker rather than by shipping less code. It is one of the few wins that costs nothing per page load and makes a whole class of navigations faster at once.

go deeper

for a junior

Be able to say plainly that a restored page comes back with scroll position and in-page state intact and does no network or script work, while a back navigation that misses is an ordinary page load.

for a middle

Explain why this is a different cache from the HTTP cache: one avoids downloading bytes, the other avoids rebuilding the page at all, so a restore also skips parsing, script execution and data fetching.

for a senior

Show that you would size the opportunity from real traffic first — which templates receive back navigations and how many — and that you would plan a refresh path for data that must not come back stale.

for a principal

Own the argument that making a whole navigation class instant for near-zero per-request cost usually outranks another round of bundle trimming, and say how you would stop a single shared change from silently losing it again.

## The two things that can happen when a user presses Back A history navigation has two very different outcomes. In the good case the browser restores the previous page from its back/forward cache: the document is brought back in the state it was in, including scroll offset, form values, and the values held in the page's JavaScript. Nothing is requested from the network, no HTML is parsed, no scripts are executed, and there is no render of an empty skeleton first. To the user it looks less like a navigation than like an undo. In the bad case the back navigation is an ordinary page load. The browser fetches the document (possibly from the HTTP cache, possibly from the network), parses it, runs the scripts, the application boots, data is fetched again, and only then does the list appear — usually scrolled back to the top. The user has to find their place again. That last part matters more than the milliseconds: losing scroll position in a long results list is a task cost, not just a latency cost. ## This is not the HTTP cache A common confusion is to assume a well-cached site gets instant back navigation for free. The HTTP cache saves you from *downloading bytes*; it does not save you from *rebuilding the page*. Even with every asset served from disk, a repeat page load still parses HTML, evaluates JavaScript, boots the app, re-runs data fetching, and re-lays-out the page. On a mid-range phone that work is often the dominant cost. The back/forward cache is the only mechanism that skips all of it, because the page was never torn down in the first place. ## Sizing the opportunity Back and forward navigations are not a rounding error. Browser vendors have reported them as roughly a tenth of desktop navigations and closer to a fifth on mobile — the exact figure varies by site, and yours is measurable from your own analytics. Some journeys are dominated by it: search results → detail → back → detail → back is the core loop of e-commerce, job boards, real-estate listings, and news indexes. On those templates a restored back navigation may be the single most common repeat interaction in the funnel, so making it instant moves a large slice of sessions. ## Why it is considered cheap leverage Most performance work trades something away. Shrinking a bundle means deleting features or splitting code and re-testing; adding a CDN costs money and adds a cache-invalidation problem; deferring scripts risks breaking behaviour. Back/forward cache eligibility is different in kind: you are not making the page smaller or faster, you are removing whatever is telling the browser "this page cannot be safely revived". The typical fix is small — a header, a listener, a third-party tag — and its payoff applies to every eligible back navigation on every page it covers, with no per-request cost. That ratio of effort to breadth is why it sits near the top of a performance backlog once it is measured. ## Where it does not help It does nothing for first visits, for forward navigation to a page the user has not seen, for reloads, or for pages opened in a fresh tab. It also does nothing for a user who never presses Back. And it has a genuine product consequence: the restored page carries the data it had when the user left it, so anything time-sensitive — a cart total, a price, a live count, an auth state that may have changed in another tab — needs a deliberate refresh path when the page comes back. That is real work, not a footnote, and it is the reason a team occasionally decides some page should not be restored. ## What to do with it in practice Treat it as a measured lever, not a checkbox. Find out what share of your navigations are back navigations and on which templates; find out what share of those are currently being restored; then decide whether closing that gap is worth more than the next item on the list. Because eligibility is binary per page load, the payoff curve is unusually steep: a single blocker on a shared layout can hold an entire site at a near-zero restore rate, and removing it can flip the whole site at once. That is also the risk — the same single change in the other direction silently loses the gain, so once you have it, it needs a guard.

  • If every asset on the page is already served from the HTTP cache, why is a missed back navigation still slow?
    Because the HTTP cache only removes download time. The document still has to be parsed, the JavaScript evaluated, the application booted and its data fetched again, and the page laid out from scratch. On a mid-range phone that CPU work usually dominates the network work, which is why a fully cached repeat load still feels like a load.
  • Which kinds of pages would you deliberately not make restorable?
    Pages whose content must never be shown stale and where refreshing on restore is expensive — a checkout total, a live availability count, or a view whose contents depend on a permission that may have changed in another tab. Restoring returns the page with its old data, so eligibility is only complete once a refresh path exists; when that costs more than the win, staying ineligible is a defensible choice.
  • A user reloads the page instead of pressing Back. Does the back/forward cache help?
    No. A reload explicitly asks the browser to fetch and rebuild the document, so there is nothing to restore. The same is true of opening the URL in a new tab, or clicking a link to a page visited earlier — those are fresh navigations. Only moving through the tab's own session history can be served by a restore.

saying these in an interview costs you the question

  • Says the HTTP cache and the back/forward cache are the same thing
  • Claims a faster server or CDN makes back navigation instant
  • Assumes back navigation is too rare to be worth measuring
  • Thinks the page re-executes its scripts on a restore
  • Believes eligibility is won by shipping a smaller bundle

context

open as a page

How would you measure, for real users, what share of your site's back navigations are served from the browser's back/forward cache — and what do those restores do to your Core Web Vitals field numbers?

level: middleimportance: should knowfreq 30%

basics

~20 s

Measure it in RUM as a ratio — restored back navigations over all back navigations, segmented per template. Restores re-report Core Web Vitals from the moment of restore, so they land in field data as very fast samples that can flatter an unsegmented average.

open as a page

Field data shows that most back navigations on your site are not being served from the browser's back/forward cache. How would you find out what is blocking them, and how would you decide which fix to ship first?

level: seniorimportance: should knowfreq 36%

basics

~20 s

Collect blocking reasons from lab and field — Chrome DevTools' Back/forward cache panel tests one page on demand, Chromium's notRestoredReasons reports real navigations — then rank fixes by how much traffic each unblocks, starting with shared headers and shared code.

open as a page

You own web performance across several product teams and want back/forward cache hit rate treated as a tracked number. How would you set a target for it, and how would you decide when chasing eligibility is not worth the engineering cost?

level: principalimportance: nice to knowfreq 18%

basics

~20 s

Set targets per template weighted by where back navigation actually happens, baseline before committing, and make the number a regression guard rather than a campaign. Stop when the remaining blockers are owned by third parties or protect product behaviour a restore would break.

open as a page