A service worker can make an adult family home web application faster and more resilient, but an unsafe update can cause flicker, stale forms, broken navigation, or loss of unsynchronized care records. The goal is not aggressive caching. It is a predictable application shell whose version changes without confusing staff or mixing old code with new data rules.
This guide covers progressive-web-app engineering, not a claim that every care workflow should operate offline. It was reviewed on August 8, 2026. Providers should maintain approved downtime procedures and verify privacy, recordkeeping, access, and resident-specific requirements.
Know what the service worker controls
The W3C Service Workers specification defines lifecycle events such as install and activate and functional events such as fetch. Once active, a worker may intercept requests inside its scope even when the page that registered it is gone.
Document:
- Registration scope
- Application routes under control
- Static assets cached during installation
- Runtime caching rules
- Data requests that must stay network-only
- Offline fallback behavior
- Current version identifier
- Supported client-build range
- Cache names and retirement policy
Do not let a generic fetch handler cache every successful response. Resident records, medication data, authorization responses, exports, and signed file URLs need explicit treatment.
Separate the application shell from resident data
Precache immutable scripts, styles, fonts, icons, and a minimal offline page. Use content-hashed asset filenames so a new deployment does not reuse old bytes under the same URL.
Avoid putting personalized HTML or API JSON into a shared cache. A response created for one signed-in user must never appear after another user signs in on the same device.
If the approved offline workflow needs resident data, store it in an authenticated, encrypted, facility-aware data layer with expiry and sync state—not an undifferentiated Cache Storage entry.
Make installation atomic
Build the precache manifest during deployment and include only files proven to exist. During install, fetch required shell assets into a versioned cache. If a required asset fails integrity or retrieval, let installation fail and keep the prior worker active.
Do not delete the old cache during install. Current pages may still depend on its assets. Mark optional assets separately so one nonessential image cannot block a critical update.
Record installation success, version, manifest checksum, and failure class without logging resident URLs or query parameters.
Coordinate activation with open pages
Calling skipWaiting() and clients.claim() can be appropriate, but immediate takeover may leave an old page running under a new fetch policy. Define compatibility between page build, service-worker version, API schema, and local storage schema.
For an incompatible release, tell open pages that an update is ready and activate after pending forms are saved or the user chooses a safe refresh. For urgent security fixes, activate promptly but preserve unsent work and explain the reload.
Use a message handshake:
- Page reports its build and pending-work state
- Waiting worker reports its version and compatibility
- Application chooses activate now, after save, or forced safety update
- New worker confirms control
- Page reloads once from a known state
Prevent reload loops by recording the version already acknowledged.
Eliminate login-page flicker
Authentication flicker often occurs when cached public HTML renders before the client learns that a valid session exists, or when protected content flashes before redirecting to login.
Use a neutral authentication-loading shell until server or trusted client session restoration completes. Do not precache personalized protected pages. Align middleware, page guards, and client state so they agree on public, pending, signed-in, and signed-out states.
Keep redirects deterministic. A login click should not alternate between two layouts because an old worker serves a stale route bundle.
Test with a saved password, an expired session, a revoked user, a slow connection, and a newly deployed build.
Choose route-specific caching strategies
Apply policy by request class:
- Content-hashed static assets: cache first
- Public marketing images: stale while revalidate with limits
- Navigation shell: network first with a safe offline fallback
- Authentication and authorization: network only
- Resident and medication APIs: network only unless an approved offline data design exists
- Reports and exports: network only, never general runtime cache
- Signed document URLs: bypass shared cache
- Write requests: never cached as responses; use a separate durable offline queue if approved
Verify method, origin, credentials, response type, and cache headers. Do not cache opaque cross-origin responses casually.
Protect unsynchronized local records
Service-worker activation, cache cleanup, and database migration must not erase local medication events or notes waiting to synchronize. Keep pending records in a versioned data store separate from disposable shell caches.
Before destructive migration, create a recoverable checkpoint and verify schema compatibility. If automatic migration cannot preserve every field, stop and route the device to assisted recovery.
The offline sync conflict-resolution guide explains stable event IDs, server receipts, conflicts, and revocation checks.
Retire caches after verifying clients
During activation, enumerate only cache names owned by this application. Delete obsolete versions by a strict prefix and explicit retention rule. Never clear all origin storage.
Keep at least the versions required by still-supported clients during a rolling deployment. When the new shell is confirmed, retire older caches and record the cleanup result.
A cache name should include product, environment, asset class, and version. This prevents a staging build or unrelated subapplication from deleting production data.
Handle API and schema compatibility
Deploy additive server changes before clients that use them. Keep older fields and endpoints for a defined compatibility window. Remove them only after monitoring shows old clients have upgraded or been blocked safely.
Include an API contract version in requests and return a clear upgrade-required response when compatibility ends. Do not allow an old medication form to submit a payload the new server interprets differently.
For local database migrations, test upgrade from every supported released version—not only from the immediately previous build.
Fail safely during partial deployments
A content delivery network may have a new HTML document before every asset is available. Use immutable assets, atomic release manifests, and deployment ordering that prevents the shell from referencing missing chunks.
If a dynamic import fails, attempt one controlled refresh after checking for a new build. Preserve form data first. If recovery fails, show a useful version and support reference instead of a blank screen.
Never loop between reload, registration, and cache deletion. Rate-limit automated recovery and keep a route that loads without the application bundle when possible.
Make update state visible but quiet
Staff should see a concise prompt when action is actually needed:
- Update ready; save and refresh
- Updating after your saved work is confirmed
- Offline; update will complete when connected
- Update failed; current safe version remains active
- This version is no longer supported; reconnect or contact support
Avoid repeated toasts on every route. Put diagnostics such as build, worker, cache, and sync versions in an authorized support panel rather than the main dashboard.
Monitor worker health
Collect privacy-preserving measures:
- Active build and worker-version distribution
- Install and activation failures
- Missing asset and chunk errors
- Controlled-reload success
- Cache size by class
- Offline fallback use
- Pending local records by age
- API-version mismatch
- Authentication redirect loops
- Blank-screen or startup timeout reports
Use opaque session and facility identifiers in technical telemetry. Do not include resident names, medication directions, document URLs, or access tokens.
Test the full lifecycle
Use a staging environment and demonstration data to verify:
- First install on a clean browser profile.
- Compatible update with no open form.
- Incompatible update while a medication form is unsaved.
- Urgent update with a pending offline event.
- Install failure leaves the old worker active.
- Missing new asset does not produce a blank screen.
- Two tabs run different page builds during activation.
- Login with a valid saved session has no flicker.
- Expired and revoked sessions show no protected flash.
- Sign-out followed by another user sign-in reveals no cached resident data.
- Old local schema migrates with all pending event fields.
- Offline reload shows only the approved shell and data.
- Cache cleanup leaves unrelated origin storage intact.
- Dynamic chunk recovery reloads at most once.
- Rollback restores a compatible worker and asset set.
Capture video and console/network traces for visible flicker or reload loops. Inspect Cache Storage and local databases after each identity switch.
Frequently asked questions
Should a new service worker always call skipWaiting immediately?
Not automatically. Choose activation based on compatibility, unsaved work, and security urgency, then test mixed page and worker versions.
Can resident API responses go into the runtime cache?
Avoid generic caching. Approved offline resident data needs authenticated scope, encryption, expiry, revocation, and a separate synchronization design.
Why does login flicker after deployment?
Common causes include cached public shells, mismatched route bundles, and competing server and client auth states. Render a neutral pending state and keep protected HTML out of precache.
When can old caches be deleted?
After the new worker is active and the supported client strategy no longer needs them. Delete only explicitly owned cache versions.
What must survive an update?
Every confirmed server record and every valid unsynchronized local event. Disposable shell assets can be replaced; care evidence cannot.
Ship faster updates without risking care records
A safe service-worker lifecycle uses immutable assets, atomic installation, compatible activation, route-specific caching, protected offline data, bounded recovery, and monitored cleanup. Staff experience a stable application instead of a deployment artifact.
Explore AFH Manager to test sign-in transitions, service-worker upgrades, offline queues, cache isolation, update prompts, and rollback behavior with demonstration records before production deployment.