pwa: serve static assets network-first so redeploys stop serving stale JS/CSS

Asset URLs are not content-hashed, so the cache-first strategy pinned
whatever bytes were first cached and never noticed a redeployed file
changed — leaving stale weather-gl.js/output.css in place until a manual
CACHE_VERSION bump. Only a hard reload (which bypasses the SW) showed the
new assets. Switch /static/ to network-first (fall back to cache offline)
and bump CACHE_VERSION v4->v5 to flush the stale shell.
This commit is contained in:
prosolis
2026-07-15 17:45:53 -07:00
parent 790a118273
commit e0d90ff7cc

View File

@@ -4,7 +4,7 @@
// //
// Bump CACHE_VERSION whenever the precached shell assets change; activate() // Bump CACHE_VERSION whenever the precached shell assets change; activate()
// drops every cache that doesn't match the current version. // drops every cache that doesn't match the current version.
var CACHE_VERSION = "v4"; var CACHE_VERSION = "v5";
var SHELL_CACHE = "pete-shell-" + CACHE_VERSION; var SHELL_CACHE = "pete-shell-" + CACHE_VERSION;
var RUNTIME_CACHE = "pete-runtime-" + CACHE_VERSION; var RUNTIME_CACHE = "pete-runtime-" + CACHE_VERSION;
@@ -117,18 +117,24 @@ self.addEventListener("fetch", function (event) {
return; return;
} }
// Static assets: cache-first (they're versioned by deploy), fill the cache on // Static assets: network-first. Our asset URLs are NOT content-hashed
// first miss so a later offline visit has them. // (/static/js/weather-gl.js stays the same URL across deploys), so a
// cache-first strategy would pin whatever bytes were first cached and never
// notice a redeployed file changed — leaving stale JS/CSS in place until the
// CACHE_VERSION bump below. Go's FileServer sets ETag/Last-Modified, so an
// online refetch is a cheap 304 when nothing changed. We still fill the cache
// on every success and fall back to it when the network is unreachable, so
// offline reading keeps the shell it needs.
if (url.pathname.indexOf("/static/") === 0) { if (url.pathname.indexOf("/static/") === 0) {
event.respondWith( event.respondWith(
caches.match(req).then(function (hit) { fetch(req).then(function (res) {
return hit || fetch(req).then(function (res) {
if (res && res.ok) { if (res && res.ok) {
var copy = res.clone(); var copy = res.clone();
caches.open(SHELL_CACHE).then(function (cache) { cache.put(req, copy); }); caches.open(SHELL_CACHE).then(function (cache) { cache.put(req, copy); });
} }
return res; return res;
}); }).catch(function () {
return caches.match(req);
}) })
); );
return; return;