CodeWalk

Service Worker 缓存策略(CacheFirst/NetworkFirst/StaleWhileRevalidate)

作者:屠龙少年 · 2026-05-30 12:55

请解释 Service Worker 中三种主要缓存策略的实现与适用场景:Cache First、Network First、Stale While Revalidate。

回答

屠龙少年

三种策略的实现代码

1. Cache First(缓存优先):离线优先,适合静态资源

async function cacheFirst(request) {
  const cached = await caches.match(request);
  if (cached) return cached;
  // 缓存没有,走网络
  try {
    const response = await fetch(request);
    // 克隆响应(因为流只能使用一次)
    const cache = await caches.open(CACHE_NAME);
    cache.put(request, response.clone());
    return response;
  } catch (err) {
    return new Response('离线不可用', { status: 503 });
  }
}
  • 适用:字体、图标、CSS、JS 等不会频繁变动的静态资源
  • 优势:快速(从缓存响应)、离线可用
  • 劣势:更新有延迟(直到缓存过期或手动清除)

2. Network First(网络优先):在线优先,适合 API

async function networkFirst(request) {
  try {
    const response = await fetch(request);
    const cache = await caches.open(CACHE_NAME);
    cache.put(request, response.clone());
    return response;
  } catch (err) {
    const cached = await caches.match(request);
    return cached || new Response('离线', { status: 503 });
  }
}
  • 适用:API 请求、频繁变化的数据
  • 优势:返回最新数据,网络失败时降级到缓存
  • 劣势:网络请求延迟

3. Stale While Revalidate(优先缓存,后台更新)

async function staleWhileRevalidate(request) {
  const cache = await caches.open(CACHE_NAME);
  const cached = await cache.match(request);
  
  const fetchPromise = fetch(request).then(response => {
    cache.put(request, response.clone());
    return response;
  }).catch(() => cached);
  
  return cached || fetchPromise;
}
  • 适用:头像、列表数据(可接受旧数据展示)
  • 优势:瞬时响应(直接返回缓存),后台异步更新
  • 最佳平衡策略

其他:Cache Only(仅缓存)、Network Only(仅网络,不缓存)。