Low bfcache usage

This health check detects pages that are not reused via the Back/Forward Cache (bfcache) based on real user data.

It highlights cases where users navigate back or forward, but the page is fully reloaded instead of instantly restored.

Each todo represents a navigation pattern where bfcache usage is lower than expected.

About this check

When this check is triggered

You’ll see this check when:

  • Back/forward navigations rarely use bfcache
  • The impact is visible in real user data (p75)
  • There are enough events to validate the pattern
  • Pages are frequently reloaded instead of restored

What you’ll see

Each todo includes:

  • bfcache usage for a set of navigations
  • Comparison with expected behavior
  • Based on real user sessions

Example:

Improve Back/Forward Cache usage
The Back/Forward Cache (bfcache) usage is lower than expected. You might have scripts that prevent back/forward caching.

Why this matters

bfcache enables instant navigation when users go back or forward. On some sites, back and forward navigations can account for up to 25% of total pageviews.

When working correctly:

  • Pages restore instantly (no network request)
  • No JavaScript re-execution
  • No layout shifts or loading states

When disabled:

  • Full reloads occur
  • TTFB, FCP, and LCP are triggered again
  • Navigation feels slow and inconsistent

How to fix it

Most bfcache issues are caused by:

  • unload or beforeunload event listeners
  • Forced reloads or redirect-based navigation
  • In-flight network requests during navigation
  • Open connections (WebSockets, IndexedDB, etc.)
  • Strict cache headers (e.g. Cache-Control: no-store)
  • Cross-origin iframes or third-party embeds
  • JavaScript relying on full page reload behavior

Possible causes and fixes:

1. Remove unload and beforeunload handlers

These are the most common blockers, though some browsers including Google Chrome already started ignoring unload event listeners.

What to check

window.addEventListener('unload', () => {});
window.addEventListener('beforeunload', () => {});

What to do

2. Avoid forced reloads

What to check

  • location.reload() on navigation
  • Redirects on page load
  • Scripts that reinitialize the app unnecessarily

What to do

  • Let the browser handle navigation state
  • Avoid forcing reloads unless required

3. Handle network requests correctly

What to check

  • fetch() or XHR still running during navigation

Example

fetch('/track'); // still running when navigating away

What to do

  • Use navigator.sendBeacon()
  • Or fetch({ keepalive: true })
  • Ensure requests complete safely

4. Clean up active resources

The page must be “freezable” for bfcache.

What to check

  • Open WebSockets
  • IndexedDB transactions
  • Long-running async work
  • Event listeners not cleaned up

What to do

  • Pause or close resources on pagehide
  • Resume them on pageshow

5. Ensure pages are cache-safe

The browser must be able to restore the page safely.

What to check

  • Auth or session-dependent rendering
  • State tied to navigation

What to do

  • Avoid relying on full reloads for state reset
  • Handle updates on pageshow

6. Review cache headers

What to check

  • Cache-Control: no-store

Why this matters

  • Pages with strict cache headers are often excluded from bfcache

7. Audit third-party and iframe behavior

What to check

  • Ads
  • Embedded tools
  • Payment widgets
  • Cross-origin iframes

Why this matters

  • These can block bfcache without clear visibility

8. Validate framework behavior

What to check

  • SPA routing logic
  • Global event listeners
  • Navigation lifecycle handling

What to do

  • Ensure compatibility with pagehide / pageshow
  • Avoid assumptions about full reloads

9. Be aware of browser limitations

Even if everything is correct:

  • Low memory
  • Tab pressure
  • Device constraints

Browsers may still choose not to use bfcache.

Further debugging

How to approach this in RUMvision

  1. Open the todo
  2. Identify affected navigation patterns
  3. Reproduce locally:
  4. Identify why the page is not eligible
  5. Fix blocking issues (events, requests, resources)
  6. Monitor improvement over the next 7 days

Pro tip

Focus on:

  • High-traffic navigation flows (product → listing → back)
  • Mobile users (more frequent back/forward usage)
  • Pages with heavy JavaScript or custom navigation logic

Improving bfcache usage can turn slow navigations into instant transitions without touching your backend or frontend performance budgets.

Enable the Track NotRestoredReasons feature to capture why pages are not restored:

performance.getEntriesByType('navigation')[0].notRestoredReasons