v149 · Demo 2

BFCache Eligibility Checker

See how a WebSocket connection affects BFCache eligibility in Chrome 149 vs earlier browsers, and understand the pattern for reconnecting on restore.

WebSocket: not connected
Open WebSocket connection
No active connection — open one above.
📜
unload event listener
This page does not add an unload listener (good — it blocks BFCache).
✓ not blocking
🔒
Cache-Control: no-store
Not set — page is cacheable.
✓ ok
🔄
Reconnect on pageshow (persisted)
Pattern: listen for pageshow with persisted: true and reopen the WebSocket.
✓ recommended
Chrome < 149

Open WebSocket → page is marked INELIGIBLE for BFCache. Back-navigation triggers a full reload (slow, bandwidth-heavy).

// Back-navigation: full reload performance.getEntriesByType('navigation') [0].type === 'reload' // true
Chrome 149+

Open WebSocket → page is ELIGIBLE. Chrome closes the socket on pagehide, stores the page, and restores it instantly.

// Back-navigation: instant BFCache restore performance.getEntriesByType('navigation') [0].type === 'back_forward' // true

reconnect pattern

let ws;

function connect() {
  const wsUrl = new URL('/v149/disconnect-websockets-on-bfcache-entry/ws', location.href);
  wsUrl.protocol = location.protocol === 'https:' ? 'wss:' : 'ws:';
  ws = new WebSocket(wsUrl);
  ws.onopen  = () => console.log('connected');
  ws.onclose = () => console.log('disconnected');
}

// Chrome 149 closes the connection automatically on pagehide (persisted).
// Reconnect when the page is restored.
window.addEventListener('pageshow', (event) => {
  if (event.persisted) {
    // Page served from BFCache — socket was closed, reopen it.
    connect();
  }
});

connect(); // Initial connect on first load

see also

implementation reference

Need the exact API surface, compatibility boundaries, errors, lifecycle, and source links? Read the matching gendn reference ↗