Service Workers 基础入门

W3C

Service Workers 基础入门

Service Worker 是运行在浏览器后台的脚本,用于实现离线功能和缓存策略。

什么是 Service Worker

Service Worker 是 PWA(渐进式 Web 应用)的核心技术,它能够:

  • 拦截网络请求
  • 缓存资源
  • 在离线时提供内容
  • 推送通知

基本生命周期

注册 → 安装 → 激活 → 运行中

注册 Service Worker

// 在主线程中注册
if ('serviceWorker' in navigator) {
  window.addEventListener('load', () => {
    navigator.serviceWorker.register('/sw.js')
      .then(registration => {
        console.log('SW 注册成功:', registration);
      })
      .catch(error => {
        console.log('SW 注册失败:', error);
      });
  });
}

安装事件

sw.js 文件中:

const CACHE_NAME = 'my-cache-v1';
const urlsToCache = [
  '/',
  '/styles/main.css',
  '/scripts/main.js',
  '/images/logo.png'
];

self.addEventListener('install', event => {
  event.waitUntil(
    caches.open(CACHE_NAME)
      .then(cache => {
        return cache.addAll(urlsToCache);
      })
  );
});

激活事件

self.addEventListener('activate', event => {
  event.waitUntil(
    caches.keys().then(cacheNames => {
      return Promise.all(
        cacheNames.map(cacheName => {
          if (cacheName !== CACHE_NAME) {
            return caches.delete(cacheName);
          }
        })
      );
    })
  );
});

拦截请求

self.addEventListener('fetch', event => {
  event.respondWith(
    caches.match(event.request)
      .then(response => {
        // 缓存命中,返回缓存的响应
        if (response) {
          return response;
        }
        // 缓存未命中,发起网络请求
        return fetch(event.request);
      }
    )
  );
});

缓存策略

Cache First (缓存优先)

self.addEventListener('fetch', event => {
  event.respondWith(
    caches.match(event.request)
      .then(response => response || fetch(event.request))
  );
});

Network First (网络优先)

self.addEventListener('fetch', event => {
  event.respondWith(
    fetch(event.request)
      .catch(() => caches.match(event.request))
  );
});

Stale While Revalidate (后台更新)

self.addEventListener('fetch', event => {
  event.respondWith(
    caches.match(event.request).then(cachedResponse => {
      const fetchPromise = fetch(event.request).then(networkResponse => {
        caches.open(CACHE_NAME).then(cache => {
          cache.put(event.request, networkResponse.clone());
        });
        return networkResponse;
      });
      return cachedResponse || fetchPromise;
    })
  );
});

更新 Service Worker

// 主线程
navigator.serviceWorker.register('/sw.js').then(registration => {
  registration.onupdatefound = () => {
    const installingWorker = registration.installing;
    installingWorker.onstatechange = () => {
      if (installingWorker.state === 'installed') {
        if (navigator.serviceWorker.controller) {
          console.log('新内容可用,请刷新页面');
        } else {
          console.log('内容已缓存');
        }
      }
    };
  };
});

调试 Service Worker

在 Chrome 中:

  1. 打开 DevTools
  2. 进入 Application 标签
  3. 左侧选择 Service Workers
  4. 查看状态、注册信息

总结

✅ Service Worker 实现离线功能
✅ 支持多种缓存策略
✅ 需要 HTTPS 环境(localhost 除外)
✅ 自动更新机制

更多详情请参考 MDN Service Worker