PWA Guide
Offline caching for assets and API
What to cache, what never to cache, and how to version caches so users do not stick on an old app shell.
All materials
1. What to cache
| Type | Cache? | Strategy |
| App shell (HTML/CSS/JS) | Yes | Precache + version bump |
| Fonts / icons | Yes | Cache First |
| Images | Selectively | Cache First with size limits |
| Public API lists | Sometimes | Network First or SWR |
| Auth / payments / private data | No | Network Only |
2. Versioning pattern
const VERSION = 'v3';
const STATIC_CACHE = `static-${VERSION}`;
const DATA_CACHE = `data-${VERSION}`;
// On activate: delete caches that do not match VERSION
self.addEventListener('activate', (event) => {
event.waitUntil((async () => {
const keys = await caches.keys();
await Promise.all(
keys
.filter((key) => !key.endsWith(VERSION))
.map((key) => caches.delete(key))
);
})());
});
Every release that changes shell files should bump VERSION.
3. Navigation offline fallback
async function handleNavigation(request) {
try {
return await fetch(request);
} catch {
return (await caches.match('/offline.html')) || Response.error();
}
}
4. Avoid sticky old apps
- Do not precache hashed assets under a forever cache name.
- Use
skipWaiting() + clients.claim() carefully; tell users when a refresh is needed.
- For HTML, prefer Network First so content updates are visible.
- Send a
Clear-Site-Data only as an emergency escape hatch.
5. Safari notes
- Storage quotas are tighter; cache only what you need.
- Do not assume long-lived offline data for rarely opened PWAs.
- Test “airplane mode” on a physical iPhone after install to Home Screen.