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
Problem
Section titled “Problem”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.
Root cause: bfcache
Section titled “Root cause: bfcache”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 backgroundedvar 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 →
pageshowfires - PWA left open, content deployed, user returns after >5 min →
visibilitychangefires - User switches to another app for 30 sec → neither fires, no disruption
Why not visibilitychange alone
Section titled “Why not visibilitychange alone”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.
Why not pageshow alone
Section titled “Why not pageshow alone”Doesn’t cover long-running sessions where the page was never frozen — just idle in the background while new content was deployed.
Deployment
Section titled “Deployment”Both pages rebuilt and FTP-deployed to talbotstevens.com/mbr/focus.html and
talbotstevens.com/sdc/focus.html.
Commit: 42d76a3 — fix(focus): bfcache + stale-session reload handlers on both PWAs