15

I build mobile web that should feel native, and the classic failure is a service worker that caches so aggressively users get a stale app for days and can't figure out why the update never lands.

My prompt makes the model pick a deliberate caching strategy per asset class (app shell, API data, images) and, crucially, ship a working update flow so a new deploy actually takes over. I tested it on a plane with airplane mode and it loaded and queued my writes.

Curious whether people prefer a toast-to-refresh or silent skipWaiting for the update handoff.

THE PROMPT
Build a Progressive Web App shell that is genuinely offline-capable and updates cleanly. Vanilla or a light framework, but the service worker logic must be explicit, not a black-box plugin.

DELIVER: manifest.webmanifest, sw.js, and the registration code.

CACHING STRATEGY (state it per class, don't cache-everything):
- App shell (html/css/js): cache-first, but versioned by a build hash so a new deploy invalidates it.
- API/data GET requests: stale-while-revalidate with a max age; never serve data older than {MAX_AGE}.
- Images: cache-first with an LRU cap of {N} entries so storage doesn't grow unbounded.
- Mutations (POST/PUT/DELETE) while offline: queue with Background Sync and replay on reconnect, in order.

UPDATE FLOW (this is the part that's usually broken):
- On a new SW version, do NOT silently skipWaiting. Post a message to the page and expose an `onUpdateAvailable` callback so the app can prompt the user, then skipWaiting + clients.claim on their confirmation.

MANIFEST: valid icons for maskable + any, standalone display, theme + background color.

CONSTRAINT: no caching of opaque cross-origin responses without a size guard; the app must load with the network fully disabled after first visit. Explain how to verify offline in DevTools.
the stale-forever service worker is my personal villain. versioning the shell by build hash is the fix i kept forgetting to demand.mira_dev 2 months ago
add a comment

2 Answers

10

The per-asset-class strategy is right, the mistake is always one blanket rule. On the update flow: I prefer the toast-to-refresh over silent skipWaiting for accessibility reasons, a screen reader user needs to know the app is about to reload and lose focus. Add to the prompt that the update prompt must be an aria-live region and move focus to the refresh button, otherwise the reload is disorienting.

THE PROMPT
Update prompt handoff: render the 'new version available' notice in an aria-live=polite region and move focus to the reload control so assistive tech announces it.
4

Queuing offline mutations with Background Sync is great until you realize Background Sync isn't supported everywhere, especially iOS. Worth adding a fallback to the prompt: if Background Sync is unavailable, replay the queue on the next 'online' event and on next app launch. Otherwise a chunk of your mobile users silently lose their offline writes.

Your Answer