Offline Caching Strategies: CacheFirst NetworkFirst
Implement Cache-First for static assets and Network-First for API responses using the Cache API and the Workbox library.
Offline Caching Strategies: CacheFirst NetworkFirst is a free Frontend Academy lesson on CoddyKit. This is lesson 3 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Frontend Academy learning path, and your progress syncs across the web and the CoddyKit app. The Frontend Academy course includes 4 lessons in total.
Why Caching Strategies Matter
Service workers can intercept every fetch — but you need a strategy. Different content needs different rules: a logo should be cached forever, an API response should always be fresh, news articles benefit from stale-while-revalidate.
The Cache API
Service workers use the Cache API: a key-value store of Request → Response pairs, scoped per origin. Persisted across sessions.
// open a cache:
const cache = await caches.open('v1');
// add resources:
await cache.add('/styles.css');
await cache.addAll(['/', '/app.js', '/styles.css']);
// look up:
const response = await cache.match('/styles.css');
// delete:
await cache.delete('/styles.css');Cache First
Check the cache first. If found, return it. If not, fall back to network and cache the response. Best for: static assets, fonts, logos, app shell.
self.addEventListener('fetch', (event) => {
event.respondWith(
caches.match(event.request).then(cached => {
if (cached) return cached;
return fetch(event.request).then(res => {
const clone = res.clone();
caches.open('v1').then(c => c.put(event.request, clone));
return res;
});
})
);
});Network First
Try network first. If it fails (offline), fall back to cache. Best for: API calls, dynamic content where freshness matters more than speed.
self.addEventListener('fetch', (event) => {
event.respondWith(
fetch(event.request).then(res => {
const clone = res.clone();
caches.open('api-v1').then(c => c.put(event.request, clone));
return res;
}).catch(() => caches.match(event.request))
);
});Stale While Revalidate
Return cache immediately (fast), then fetch in the background and update the cache for next time. Best for: avatars, news articles, semi-fresh data.
self.addEventListener('fetch', (event) => {
event.respondWith(
caches.match(event.request).then(cached => {
const network = fetch(event.request).then(res => {
caches.open('v1').then(c => c.put(event.request, res.clone()));
return res;
});
return cached || network;
})
);
});Network Only
Bypass the cache entirely — always go to network. Use for non-cacheable requests (auth endpoints, analytics, mutations).
self.addEventListener('fetch', (event) => {
if (event.request.url.includes('/api/auth')) {
event.respondWith(fetch(event.request));
return;
}
// ... other strategies
});Cache Only
Never go to network — return cache or fail. Useful for files you precached and never want to refresh during a session.
Workbox Strategies
Workbox bundles all strategies as named classes. Less boilerplate.
import { registerRoute } from 'workbox-routing';
import { CacheFirst, NetworkFirst, StaleWhileRevalidate } from 'workbox-strategies';
registerRoute(({ request }) => request.destination === 'image',
new CacheFirst({ cacheName: 'images' })
);
registerRoute(({ url }) => url.pathname.startsWith('/api/'),
new NetworkFirst({ cacheName: 'api', networkTimeoutSeconds: 3 })
);
registerRoute(({ request }) => request.destination === 'document',
new StaleWhileRevalidate({ cacheName: 'pages' })
);Cache Expiration
Caches grow forever unless you set limits. Workbox provides ExpirationPlugin.
import { ExpirationPlugin } from 'workbox-expiration';
new CacheFirst({
cacheName: 'images',
plugins: [new ExpirationPlugin({
maxEntries: 50,
maxAgeSeconds: 30 * 24 * 60 * 60 // 30 days
})]
});Cacheable Response
By default, browsers cache only 200 responses. Skip 4xx, 5xx, and opaque (cross-origin no-cors) responses to avoid filling the cache with errors.
Offline Fallback Page
Show a friendly offline page when a navigation fails — better UX than the browser's default error.
self.addEventListener('install', (e) => {
e.waitUntil(caches.open('offline').then(c => c.add('/offline.html')));
});
self.addEventListener('fetch', (e) => {
if (e.request.mode === 'navigate') {
e.respondWith(
fetch(e.request).catch(() => caches.match('/offline.html'))
);
}
});Choosing the Right Strategy
Static assets (logo, font, CSS): Cache First. API data (user profile, feed): Network First. Sometimes-fresh content (avatars, news): Stale While Revalidate. Authentication: Network Only. Pre-installed static files: Cache Only.
Quick Check
Which caching strategy is best for a CSS file that rarely changes but must load fast?
Recap: Caching Strategies
Cache First: static assets (fastest, may be stale). Network First: API data (freshest, slower). Stale While Revalidate: serve cache + fetch in background. Network Only: auth/mutations. Cache Only: pre-installed shell. Use Workbox for less boilerplate. Set expiration limits. Add an offline fallback page. Pick per resource type.
Learn HTML with an AI tutor — free
Write and run real code in your browser, get instant help from a 24/7 AI tutor, and pick up where you left off on the web or in the app.
- Courses
- 41
- Lessons
- 163
Frequently Asked Questions
Is the “Offline Caching Strategies: CacheFirst NetworkFirst” lesson free?
Yes — the full text of “Offline Caching Strategies: CacheFirst NetworkFirst” is free to read here on the web. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Frontend Academy course, upgrade to CoddyKit PRO. The Frontend Academy course includes 4 lessons in total.
What will I learn in “Offline Caching Strategies: CacheFirst NetworkFirst”?
Implement Cache-First for static assets and Network-First for API responses using the Cache API and the Workbox library. You practise Frontend Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start Frontend Academy?
No prior experience is required. Frontend Academy on CoddyKit is structured for beginners through advanced learners, so you can start here or from the beginning and move at your own pace. This is lesson 3 of 4.
How long does the “Offline Caching Strategies: CacheFirst NetworkFirst” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this Frontend Academy lesson?
Yes. Every Frontend Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- The Web App Manifest
- Service Worker Registration and Lifecycle
- Offline Caching Strategies: CacheFirst NetworkFirst
- Push Notifications