PWA features for UX improvements
PWAs add: installable to home screen (manifest), offline + cached shell (service worker), background sync for queued mutations, push notifications, faster repeat loads via cache-first asset strategies, share targets, and OS-level integration. Best wins: instant repeat load and resilient-on-flaky-network. Cost: SW complexity and update gotchas.
PWA features turn a web app from "tab" into "app-like" — installable, offline-capable, and notification-aware. They're a UX upgrade, not a rewrite.
1. Installable — Web App Manifest
A manifest.json declares name, icons, theme color, display mode (standalone), start URL.
{ "name": "My App", "short_name": "App", "start_url": "/", "display": "standalone", "icons": [...], "theme_color": "#0a0a0a" }Browsers offer "Install" once criteria are met (HTTPS, manifest, SW). Installed PWAs open without browser chrome — feels native.
2. Service Worker — offline + fast repeat loads
A SW is a proxy that intercepts network requests. Two big wins:
- App shell cached — instant boot on repeat loads (cache-first for shell assets).
- Offline pages — show a useful page (or cached data) with no network.
Strategies (Workbox terminology):
- Cache-first — fonts, icons, immutable hashed bundles.
- Stale-while-revalidate — HTML/JS that updates often but should load instantly.
- Network-first — API responses where freshness matters.
- Network-only — auth, real-time.
3. Background sync
Queue mutations made offline; replay them when the network returns:
self.addEventListener("sync", (event) => {
if (event.tag === "post-message") event.waitUntil(flushQueuedPosts());
});The user posts a comment offline → "Sent" appears optimistically → the SW replays it when online.
4. Push notifications
The Push API + Notification API let your server wake the browser (or installed PWA) and show a system notification. Requires user permission. Use sparingly — over-prompting kills install/retention.
5. Other UX-relevant APIs
- Share Target — your PWA appears in the OS share sheet.
- File System Access — open/save local files (Chromium-only).
- Periodic Background Sync — background refresh (limited browsers).
- Badging — unread count on the app icon.
6. Best UX wins (priority order)
- Instant repeat loads — cache the shell + critical assets. Biggest perceived-perf win on mobile.
- Resilient on flaky network — degrade to cached content; queue mutations.
- Installable — for return users who use it daily.
- Push — only if there's a real notify-worthy event.
7. Costs and gotchas
- SW update model — a new SW activates only after all tabs close, by default. Use
skipWaiting()+ a banner ("Update available — Reload") so users see new versions. - Cache invalidation — versioned cache names; clean up old caches on activate.
- Debugging — stale SWs cause weird "I deployed but the bug persists" reports. Add a kill-switch.
- HTTPS required — and a non-trivial setup story.
- iOS Safari has limited Push and install support — feature parity is uneven.
Interview framing
"PWA features layer onto a normal web app. The biggest UX wins are instant repeat loads via a service-worker-cached app shell and resilience to flaky networks via cache fallbacks and background sync for queued mutations. Installable via a manifest gives an app-like experience for return users; push notifications are powerful but easy to overuse. The cost is service-worker complexity — especially the update model, which needs a 'reload to update' UX so users aren't stuck on stale code. I'd reach for Workbox rather than hand-roll caching strategies."
Follow-up questions
- •What's the service worker update flow and what's the gotcha?
- •Cache-first vs stale-while-revalidate vs network-first — when to use which?
- •Why is background sync valuable for mobile users?
- •What are PWA limitations on iOS?
Common mistakes
- •Caching API responses cache-first → users see stale data forever.
- •No update prompt — users on the old SW indefinitely.
- •Push-permission prompt on first load → users dismiss permanently.
- •Treating PWA as a replacement for native when feature parity isn't there (especially iOS).
Performance considerations
- •Cached shell makes repeat loads near-instant. Cache only what's hot; clean up old caches; watch quotas. SW startup adds a small first-request cost — measure.
Edge cases
- •User installs, then your domain changes.
- •Service worker bug shipped — need a kill-switch.
- •Cache quota exceeded.
- •Update lands while user is in the middle of a flow.
Real-world examples
- •Twitter Lite, Pinterest's PWA, Starbucks' ordering PWA — all reported significant repeat-load and conversion wins.