fix(pwa): network-first navigation so a new deploy loads online immediately #200

Merged
developer merged 1 commits from feature/sw-fresh-online into development 2026-07-06 15:05:37 +00:00
Owner

The C1 precache service worker served the precached shell for every navigation — even online — so a new deploy only reached a client after the worker updated its precache in the background (a one-launch lag). A cold online start showed the old version until then; a reinstall forced it fresh (owner-observed on the contour).

Fix

  • sw.ts — network-first navigation: fetch the fresh (no-cache) shell from the server on each online launch (it references the new hashed assets, fetched fresh), with a 3 s timeout falling back to the precached shell when the network is unreachable or too slow. Only the tiny HTML is re-fetched; the immutable hashed assets stay cache-first and re-download only when their hash (= the version) changes. Offline cold-launch still works via the fallback. No new dep — the handler is ~12 hand-written lines (given the dep-weight concern on the earlier Workbox PR).
  • webui.go — sw.js no-cache: so the browser reliably detects a new deploy's worker (regression-tested).

Why not an explicit version check (the idea we discussed)

The immutable hashed assets already give version-gating — they re-download only when the hash changes. Only the tiny no-cache HTML is re-fetched each online launch. So an explicit version comparison would be redundant (and would need a version scheme the test contour lacks). And there's no reload flash: the fresh shell loads on the initial launch, behind the splash.

Tests

Go: webui (sw.js served as JS + no-cache) — green. UI: check (0), e2e (196), build (generates dist/sw.js with the network-first nav), gate 112.8/113.

⚠️ Online-launch freshness is contour-verified — the mock e2e disables the SW, so there is no automated test of the worker's navigation strategy. Please deploy this, then deploy any trivial change on top and confirm the second one loads without a reinstall.

Next (the shared-root task): the offline auto-detect (round-1's "network unreachable at cold start → offline after one cycle") + folding connection.svelte into a clean offline/slow/online detector.

The C1 precache service worker served the precached shell for **every** navigation — even online — so a new deploy only reached a client after the worker updated its precache in the background (a one-launch lag). A cold online start showed the old version until then; a reinstall forced it fresh (owner-observed on the contour). ## Fix - **sw.ts — network-first navigation**: fetch the fresh (no-cache) shell from the server on each online launch (it references the new hashed assets, fetched fresh), with a **3 s timeout** falling back to the precached shell when the network is unreachable or too slow. Only the tiny HTML is re-fetched; the immutable hashed assets stay cache-first and re-download only when their hash (= the version) changes. Offline cold-launch still works via the fallback. **No new dep** — the handler is ~12 hand-written lines (given the dep-weight concern on the earlier Workbox PR). - **webui.go — `sw.js` `no-cache`**: so the browser reliably detects a new deploy's worker (regression-tested). ## Why not an explicit version check (the idea we discussed) The immutable hashed assets already give version-gating — they re-download only when the hash changes. Only the tiny no-cache HTML is re-fetched each online launch. So an explicit version comparison would be redundant (and would need a version scheme the test contour lacks). And there's no reload flash: the fresh shell loads on the initial launch, behind the splash. ## Tests Go: webui (`sw.js` served as JS + `no-cache`) — green. UI: `check` (0), e2e (196), `build` (generates `dist/sw.js` with the network-first nav), gate 112.8/113. ⚠️ Online-launch freshness is **contour-verified** — the mock e2e disables the SW, so there is no automated test of the worker's navigation strategy. Please deploy this, then deploy any trivial change on top and confirm the second one loads without a reinstall. **Next** (the shared-root task): the offline **auto-detect** (round-1's "network unreachable at cold start → offline after one cycle") + folding `connection.svelte` into a clean offline/slow/online detector.
developer added 1 commit 2026-07-06 14:45:48 +00:00
fix(pwa): network-first navigation so a new deploy loads online immediately
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Successful in 10s
CI / integration (pull_request) Successful in 18s
CI / ui (pull_request) Successful in 1m10s
CI / conformance (pull_request) Successful in 9s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m43s
020742fad3
The C1 service worker served the precached shell for every navigation, even
online, so a new deploy only reached a client after the worker updated its
precache in the background (a one-launch lag): a cold online start showed the
old version until then, and only a reinstall forced it fresh.

- sw.ts: navigations are now network-first — fetch the fresh (no-cache) shell
  from the server on each online launch (it references the new hashed assets,
  fetched fresh), with a 3s timeout falling back to the precached shell when the
  network is unreachable or too slow. Only the tiny HTML is re-fetched; the
  immutable hashed assets stay cache-first and re-download only when their hash
  (the version) changes. Offline cold-launch still works via the fallback.
- webui.go: serve sw.js with Cache-Control: no-cache so the browser reliably
  detects a new deploy's worker (regression-tested).

Online launch is contour-verified (the mock e2e disables the SW); e2e 196.
No new deps — the network-first handler is hand-written (~12 lines).
owner approved these changes 2026-07-06 14:47:21 +00:00
Dismissed
owner approved these changes 2026-07-06 15:04:42 +00:00
developer merged commit 2a7c632840 into development 2026-07-06 15:05:37 +00:00
developer deleted branch feature/sw-fresh-online 2026-07-06 15:05:37 +00:00
Sign in to join this conversation.
No Reviewers
No Label
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: developer/scrabble-game#200