The visible problem may look like one API or tuning value, but reliability is decided by state ownership, resource bounds, and recovery after failure. Forced skipWaiting deploys quickly but can pair old page code with a new worker. Incompatible caches, APIs, or messages split one live task across versions.
Browser capability depends on version, permission, visibility, and device policy. Use capability detection and an explained fallback instead of treating one development machine as the product contract.
Make the implementation decisions explicit
List non-negotiable invariants before selecting performance knobs. Tuning can roll out gradually; identity, permission, and terminal-state rules cannot drift at runtime.
- Expose build versions to page and worker and check for active transfers or shares before activation.
- Keep the new worker waiting and offer update-after-task plus an explicit immediate update.
- Version cache names and delete an old cache only after no client still relies on it.
A Service Worker update is a live version migration. Activation follows active-task policy, and protocol compatibility belongs in release tests.
Failure paths that are easy to miss
Failure and success must share one state model. An error toast that neither releases resources nor propagates a terminal state leaves dirty work for the next recovery attempt.
- Automatic claim sends old-page messages to a new schema parser.
- The update prompt loops because reload never confirms the target version is active.
- Old caches are deleted offline before new assets exist, breaking both shell and active work.
How to verify it before release
Do not stop verification when the final action succeeds. Count side effects, measure wait time, inspect privacy, and prove the next run begins from a clean baseline.
- Release a worker at 1 percent, 50 percent, and verification; task behavior must match policy.
- Run two versions across tabs and verify old caches disappear only after the last old client closes.
- Lose network during update and prove the old shell still starts without a half-updated state.
A capability becomes maintainable when it degrades safely, repetition adds no side effects, and its signals reveal a fault before user reports do.