← Recipes

阅读中文版本

Cache API Responses in a Service Worker

Apply a stale-while-revalidate strategy in a service worker so repeat visits render instantly and refresh in the background.

~35 minfrontendcachingservice-worker

Task

Implement stale-while-revalidate caching for API GET requests in a service worker.

When to use this

Repeat visits re-request the same data, making the app feel slow even though the data rarely changes.

Prerequisites

  • A service worker registered
  • A cache API available
  • API GET endpoints

Steps

1. Serve cached responses and refresh in the background.

self.addEventListener('fetch', (event) => {
  const { request } = event;
  if (request.method !== 'GET') return;
  event.respondWith((async () => {
    const cache = await caches.open('api-v1');
    const cached = await cache.match(request);
    const fetched = fetch(request).then((res) => { cache.put(request, res.clone()); return res; });
    return cached || fetched;
  })());
});

Expected output: Repeat requests return the cached response while a fresh one is fetched for next time.

2. Verify cached responses are served and updated.

curl -s http://localhost:4321/api/data | head -c 40
# reload and confirm the response is refreshed from the network

Expected output: The cache is populated on first load and updated in the background on later loads.

Troubleshooting

Problem

Stale data shown too long

Solution

Version the cache name and expire entries; avoid caching authenticated mutations.

Problem

Cache breaks auth

Solution

Do not cache requests carrying credentials unless explicitly scoped.

Limitations

  • Stale-while-revalidate shows stale data briefly.
  • Cache storage is limited and evictable.
  • Requires careful versioning.

What this recipe does

Implement stale-while-revalidate caching for API GET requests in a service worker.

Repeat visits re-request the same data, making the app feel slow even though the data rarely changes.

Prerequisites

  • A service worker registered
  • A cache API available
  • API GET endpoints

Procedure

  1. Serve cached responses and refresh in the background.
self.addEventListener('fetch', (event) => {
  const { request } = event;
  if (request.method !== 'GET') return;
  event.respondWith((async () => {
    const cache = await caches.open('api-v1');
    const cached = await cache.match(request);
    const fetched = fetch(request).then((res) => { cache.put(request, res.clone()); return res; });
    return cached || fetched;
  })());
});

Expected result: Repeat requests return the cached response while a fresh one is fetched for next time.

  1. Verify cached responses are served and updated.
curl -s http://localhost:4321/api/data | head -c 40
# reload and confirm the response is refreshed from the network

Expected result: The cache is populated on first load and updated in the background on later loads.

How to confirm it worked

Run the commands above and confirm every expected result in order. If a step does not produce the stated output, use the troubleshooting notes before continuing. A passing run shows repeat visits serve cached responses instantly while the cache refreshes from the network in the background.

Troubleshooting

Stale data shown too long — Version the cache name and expire entries; avoid caching authenticated mutations.

Cache breaks auth — Do not cache requests carrying credentials unless explicitly scoped.

Limitations

  • Stale-while-revalidate shows stale data briefly.
  • Cache storage is limited and evictable.
  • Requires careful versioning.