Progressive Web Apps (PWA)
debt(d3/e5/b5/t5)
Closest to 'default linter catches the common case' (d3), Lighthouse PWA audits automatically flag missing manifest, service worker, HTTPS, and offline fallback — it's a standard automated check in dev tools.
Closest to 'touches multiple files / significant refactor in one component' (e5), quick_fix involves adding a manifest, registering a service worker with caching strategies, and adding install prompts — spans multiple files and concerns within the frontend.
Closest to 'persistent productivity tax' (b5), service worker caching strategy becomes a permanent consideration for every asset and API call; applies broadly across the web frontend and shapes deploy/cache-invalidation workflows.
Closest to 'notable trap' (t5), the misconception that PWAs require a JS framework is common, and common_mistakes show documented gotchas (caching API responses indefinitely, missing offline fallback, scope issues) that most devs learn the hard way.
Also Known As
TL;DR
Explanation
A PWA requires three things: HTTPS (required for service workers), a web app manifest (JSON describing the app for installation), and a service worker (JavaScript that intercepts network requests and manages caching). Capabilities: install to home screen (A2HS), offline functionality, push notifications, background sync, and access to some device APIs. PWAs are progressively enhanced — they work as normal websites for browsers without service worker support. For PHP-rendered apps, PWA techniques add mobile app qualities without a native app.
Diagram
flowchart TD
subgraph PWA_Requirements
HTTPS[HTTPS required]
MANIFEST[Web App Manifest<br/>name icons theme]
SW[Service Worker<br/>offline caching]
end
HTTPS & MANIFEST & SW --> PWA[Progressive Web App]
PWA --> INSTALL[Install to home screen]
PWA --> OFFLINE[Works offline]
PWA --> PUSH[Push notifications]
subgraph Cache_Strategy
SW -->|static assets| CACHE_FIRST[Cache first]
SW -->|API calls| NET_FIRST[Network first<br/>fallback to cache]
end
style PWA fill:#6e40c9,color:#fff
style INSTALL fill:#238636,color:#fff
style OFFLINE fill:#238636,color:#fff
style CACHE_FIRST fill:#1f6feb,color:#fff
style NET_FIRST fill:#d29922,color:#fff
Common Misconception
Why It Matters
Common Mistakes
- Service worker that caches everything including API responses without expiry — stale data shown indefinitely.
- Not providing a fallback offline page — a blank screen is worse than a 'You are offline' message.
- Manifest without all required icons — installation prompts fail silently without the required icon sizes.
- Registering the service worker without scoping it correctly — it may intercept requests it should not.
Code Examples
// Service worker caches everything forever — stale data:
self.addEventListener('fetch', event => {
event.respondWith(
caches.match(event.request).then(cached => {
return cached || fetch(event.request).then(response => {
caches.open('v1').then(cache => cache.put(event.request, response.clone()));
return response;
});
})
);
// API responses cached indefinitely — user sees week-old data
});
// Cache-first for assets, network-first for API:
self.addEventListener('fetch', event => {
const url = new URL(event.request.url);
if (url.pathname.startsWith('/api/')) {
// Network-first for API — fresh data, fallback to cache:
event.respondWith(fetch(event.request).catch(() => caches.match(event.request)));
} else {
// Cache-first for static assets:
event.respondWith(caches.match(event.request).then(c => c || fetch(event.request)));
}
});