Skip to content

Focus Pages — bfcache + Stale-Session Reload Fix

Section titled “Focus Pages — bfcache + Stale-Session Reload Fix”

Date: 2026-06-23 Files: sites/mbr/src/pages/focus.astro, sites/sdc/src/pages/focus.astro Follows: 2026-06-20_Focus-Pages-Cache-Fix


MBR focus page PWA showed stale content on first open even when the app had been fully closed on Android. Second open showed correct content.

The 2026-06-20 fix (Cache-Control: no-cache, must-revalidate) addressed HTTP heuristic caching, but not this failure mode.


Android Chrome standalone PWAs preserve frozen page state when swiped away from Recent Apps. On re-launch, Chrome restores from the back-forward cache (bfcache) — no network request is made, so no-cache, must-revalidate never fires. The page wakes up displaying whatever HTML was frozen when the app was last backgrounded.

The exact symptom (stale first open, fresh second open) is the fingerprint: second open actually navigates fresh, triggering revalidation. First open skips the network entirely.


Two handlers added to the <script is:inline> block in both focus pages:

// Freshness: reload on bfcache restore or after 5 min backgrounded
var lastLoadTime = Date.now();
window.addEventListener('pageshow', function(e) {
if (e.persisted) window.location.reload();
});
var STALE_MS = 5 * 60 * 1000;
document.addEventListener('visibilitychange', function() {
if (!document.hidden && Date.now() - lastLoadTime > STALE_MS) {
window.location.reload();
}
});

Handler 1 — pageshow + persisted: Fires exactly when a page is restored from bfcache. event.persisted === true means no network request was made. Immediate reload.

Handler 2 — visibilitychange + time gate: Fires when the page becomes visible after being backgrounded. The 5-minute gate prevents jarring reloads on quick app switches (< 5 min) while catching the “deployed while PWA was open/backgrounded” scenario (deploy → verify → switch to phone is ~2–3 min).

Together these cover the full state machine:

  • Closed PWA relaunched via home screen → bfcache restore → pageshow fires
  • PWA left open, content deployed, user returns after >5 min → visibilitychange fires
  • User switches to another app for 30 sec → neither fires, no disruption

Without the time gate it reloads on every app switch, including 10-second checks. Jarring for a display page. The gate is the professional distinction.

Doesn’t cover long-running sessions where the page was never frozen — just idle in the background while new content was deployed.


Both pages rebuilt and FTP-deployed to talbotstevens.com/mbr/focus.html and talbotstevens.com/sdc/focus.html.

Commit: 42d76a3fix(focus): bfcache + stale-session reload handlers on both PWAs