0Pricing
Frontend Academy · Lesson

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 — 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, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

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.

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, and the Frontend Academy course includes 4 lessons in total. 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.

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; this is — lesson 3 of 4, so you can start here or from the beginning and move at your own pace.

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

  1. The Web App Manifest
  2. Service Worker Registration and Lifecycle
  3. Offline Caching Strategies: CacheFirst NetworkFirst
  4. Push Notifications
← Back to Frontend Academy