Website-Pflichtencheckby Jurono
PerformanceWebsiteTechnicalCodeMaintenanceNews

The Back Button Does Not Always Reload: Auditing bfcache After `no-store`

Chrome can restore some `Cache-Control: no-store` pages from bfcache. Learn how to test logout, stale data, forms, analytics, and page lifecycle.

By Jurono
Updated: August 8, 2026

The browser Back button looks simple: leave a page, go back, load the page again. For modern browsers, that mental model is often wrong.

Browsers can keep a page in the back/forward cache (bfcache) as a complete in-memory snapshot. When the user navigates backward or forward, the browser may not perform a normal reload at all. The DOM, JavaScript heap, and page state can reappear while JavaScript execution, paused when the user left, resumes.

That is excellent for performance. It can also expose fragile assumptions when an application expects every return visit to trigger a fresh request, a new authorization check, another analytics event, or a complete data fetch.

And since 2025, one common assumption is even less reliable: in Chrome, Cache-Control: no-store no longer automatically means “this page can never return from bfcache.”

What Chrome changed

Chrome expanded bfcache eligibility for certain pages that use Cache-Control: no-store. Chrome for Developers says the final rollout reached 100% of users during March and April 2025.

This is not Chrome ignoring sensitive-data concerns. It applies additional safeguards. Among other things, Chrome evicts affected no-store pages from bfcache when cookies or other authorization mechanisms change. APIs such as WebSocket, WebTransport, and WebRTC continue to make these no-store pages ineligible, and the bfcache timeout for them is shorter.

The architectural point remains important:

The HTTP cache and bfcache are different mechanisms.

Cache-Control: no-store primarily controls storage of HTTP responses. bfcache preserves the state of an already loaded page in memory. If your application used no-store as a universal “Back button protection,” that assumption now deserves an explicit test.

Why ordinary websites should care

This sounds like browser-engine trivia until it meets a real user journey.

1. Logout and authenticated pages

A user opens their account, navigates elsewhere, logs out in another tab, then returns with the Back button.

The correct outcome is obvious: protected information must not be treated as an active authorized session.

Chrome has safeguards around cookie and authorization changes for no-store pages, but that is not a substitute for application testing. Authentication may involve cookies, tokens, server-side sessions, client-side state, and third-party SDKs. The meaningful question is not whether Chrome has a heuristic. It is whether your real logout flow reliably prevents a restored interface from behaving as if the user were still authorized.

2. Stale data after Back

A pricing page, basket, booking list, or admin dashboard can return exactly as the user left it a minute ago.

Sometimes that is ideal. A visitor returning to a long article list probably wants the same scroll position and filters.

For dynamic data, the same behavior can be wrong:

  • An order was cancelled elsewhere.
  • A permission was revoked.
  • The basket changed in another tab.
  • Availability is no longer current.
  • A form suggests an action is still possible.
  • A dashboard shows values that became stale after a mutation.

The answer is not to disable bfcache everywhere. The answer is to distinguish between state that should be preserved and state that must be revalidated when the page becomes active again.

3. Analytics may miss or misclassify return navigation

A bfcache restore is not a normal full page load. If pageviews are emitted only from load, a framework mount, or initial startup code, back/forward navigation may be measured differently from what the analytics model expects.

web.dev recommends accounting for the pageshow event. It fires when a page is restored from bfcache, and event.persisted can indicate that the page came from a preserved state.

That does not mean every pageshow should automatically fire another pageview. The correct behavior depends on the measurement model. The important part is making a deliberate decision about whether history navigation counts as a view, a navigation event, or neither.

4. Forms can look “half submitted”

A user completes a form, submits it, reaches a confirmation page, and presses Back.

Depending on the implementation, the previous page may return with old input values, disabled buttons, local validation state, or an outdated success/error message. The dangerous version is an interface that appears to offer an action again even though the server already processed it.

Business-critical actions therefore need server-side idempotency or an equivalent transaction model where duplicate execution would cause harm. Browser navigation should never be the only protection against repeated actions.

5. Single-page applications overestimate their lifecycle

React, Vue, Next.js, and similar stacks can encourage the assumption that components will remount cleanly whenever the user “comes back.” A bfcache restore can instead resume the existing document state.

Code that runs only during initialization is therefore not automatically the right place for every freshness check. Critical state should be tied to the actual page lifecycle.

The useful audit question: what really happens when the user goes Back?

A bfcache audit should not stop at asking whether a page is cacheable. It should answer two questions:

  1. Can the page benefit from bfcache?
  2. Do security, data freshness, measurement, and business logic remain correct when it is restored?

Both goals matter. Forcing a page out of bfcache because the application does not understand its own lifecycle throws away performance. Optimizing blindly for bfcache without testing sensitive state creates functional risk.

Eight practical test cases

1. Sign in → protected page → sign out → Back

Run the flow in one tab, then repeat it with the logout occurring in another tab. Do not only inspect the UI. Attempt a real protected action.

Expected result: no stale interface should imply valid authorization, and protected requests must still be rejected server-side.

2. Change data → navigate away → Back

Modify a record from another tab or session, then return through browser history.

Ask: must the visible state update immediately, or is the preserved state acceptable for this workflow?

3. Submit a form → Back

Inspect fields, validation messages, loading state, and the submit action. Pay special attention to operations that must not execute twice.

4. Change consent state

Modify cookie or tracking preferences, navigate away, and return. Verify that embeds, tag management, and the visible consent UI represent the current state.

5. Switch language, theme, or account

Global settings are often stored client-side. A restored snapshot should not indefinitely show the previous identity, language, or theme when the underlying state changed.

6. Analytics and performance measurement

Compare a normal navigation with a back/forward restore. Are pageviews counted twice, not at all, or intentionally separated? Are performance metrics being interpreted as if every navigation were a cold page load?

7. Real-time connections

WebSocket, WebRTC, and related connections have their own lifecycle requirements. Verify whether they reconnect correctly, pause safely, or intentionally make the page ineligible for bfcache.

8. Multiple browsers

Chrome, Safari, and Firefox all implement bfcache, but their eligibility rules are not identical. A Chrome-specific safeguard is not a cross-browser contract.

Use pageshow for targeted revalidation

For pages that need to verify state after a restore, pageshow is a useful lifecycle point.

When event.persisted is true, the page has returned from a preserved state. That is an opportunity to revalidate only the data that genuinely needs to be current:

  • session or account state
  • critical permissions
  • basket or booking state
  • time-sensitive pricing or availability
  • consent configuration
  • server-side data changed elsewhere

The key word is targeted. Hard-reloading the whole application on every Back click destroys much of the performance benefit bfcache is designed to provide.

A better pattern is to let the browser restore the visual state instantly, then revalidate sensitive data in the background. If something changed, update the interface deliberately.

Why unload is not a good escape hatch

Legacy code often attaches cleanup logic to unload. That is a poor foundation today.

web.dev warns that unload is unreliable and can prevent bfcache usage in some browsers. Depending on the task, pagehide, visibilitychange, and pageshow are better lifecycle primitives.

So the goal should not be: “How can we break bfcache using an old event?”

It should be: “How do we make our page state correct when a page is paused and later resumed?”

Testing bfcache in Chrome DevTools

Chrome DevTools provides a dedicated back/forward cache test in the Application panel. It can attempt a bfcache restore and report reasons why a page could not be restored.

That is useful for two opposite classes of defect:

  • A page should benefit from instant history navigation but unnecessary code prevents it.
  • An application appears correct but has never been tested under a real preserved-state restore.

For production telemetry, the notRestoredReasons API can also provide information about why a history navigation was not served from bfcache. This becomes valuable when real users have browser, iframe, or third-party combinations that local tests do not reproduce.

Audit red flags

  • Cache-Control: no-store is treated as the only protection against back navigation.
  • Logout is tested only by clicking the button, never by navigating Back afterward.
  • Authorization is represented as frontend visibility rather than enforced server-side permission.
  • Critical data is fetched only on initial load.
  • Analytics has no model for bfcache restores.
  • Forms can accidentally repeat an operation after history navigation.
  • Third-party code registers unload handlers and silently blocks bfcache.
  • Nobody tests Safari or Firefox because the Chrome test passed.
  • Teams disable bfcache globally instead of fixing the underlying state model.

What Website-Pflichtencheck would inspect

A bfcache and history-navigation review can examine:

  • actual bfcache behavior across representative page types
  • Cache-Control headers and their intended purpose
  • login, logout, and role changes
  • behavior after session or consent changes
  • forms and non-repeatable actions
  • data freshness after back/forward navigation
  • pageshow, pagehide, visibilitychange, and problematic unload handlers
  • analytics and performance measurement
  • WebSocket and real-time components
  • differences between Chrome, Safari, and Firefox
  • DevTools and Lighthouse findings
  • regression tests for critical user journeys

bfcache is not a browser defect to switch off. It is a real page-lifecycle behavior that modern websites need to handle.

The Back button no longer guarantees a new page load. If your security, data, or measurement logic depends on that assumption, the fragile part is not the browser — it is the assumption.

Jurono logo

Jurono

Technical website audits, website fixes, and AI code rescue for small businesses, practices, law firms, and founders in Germany.

Get our free security checklist before you go.

Download free PDF

Want a first signal in 30 seconds? Run the free website quick test.

Get website notes by email

One short technical note every two weeks. No spam, no sales pitch.

Matching offers

Move forward directly

Based on the topics in this article — without a long search.

Manual Website Check

When nobody is sure which scripts, cookie signals, or technical risks are currently running on the site.

249

Manual technical first assessment and clear priorities within two business days.

  • Quickly see whether tracking, cookies, external services, or HTTPS look suspicious
  • Mobile, load time, and technical issues explained in plain language
  • The most important points in a short priority list
Get clarity with Manual Website Check

AI Code Triage

When the project starts, but nobody knows why it keeps breaking.

390

Code review, build/import check, and rescue plan within two business days.

  • Repository check for broken imports, missing packages, and build errors
  • Assessment: repair, restructure, or discard
  • Prioritized fix list with effort estimate
Secure AI Code Triage

Technical Website Audit

When the website matters, but nobody knows which visible required areas, technical risks, and fixes actually have priority.

549

Audit, assessment, and concrete action plan within 3-5 business days.

  • Everything from the manual website check, assessed and documented in more depth
  • Concrete findings for cookie, tracking, and external service signals
  • Visible required areas checked technically, without legal advice
A good fit: Technical Website Audit

Get clarity before you commit to fixes.

Start with a technical check. If the findings are minor, you can stop there, hand the report to your existing team, or book targeted fixes later.

Technical audit and implementation, not legal advice. I check visible signals, integrations, and delivery issues; legal texts and binding legal assessments remain the work of lawyers or privacy consultants.

The Back Button Does Not Always Reload: Auditing bfcache After `no-store`