Service Worker通过缓存策略实现离线访问和性能优化,需先注册并经历安装、激活等生命周期阶段。采用缓存优先、网络优先或先缓存后更新等策略可提升资源加载效率,结合版本控制与缓存清理确保数据有效性,仅在HTTPS或本地环境中使用。

Service Worker 是实现离线体验和高效资源加载的核心技术。通过编写自定义缓存逻辑,可以大幅提升网页性能和可用性。关键在于合理选择缓存策略,结合实际场景动态处理网络请求。
理解 Service Worker 生命周期
在实现缓存前,需确保 Service Worker 能正确注册并激活。它独立运行在浏览器后台,不依赖页面生命周期。
主要阶段包括:
- 注册:在主页面中调用
navigator.serviceWorker.register() - 安装(install):首次注册时触发,适合预缓存核心资源
- 激活(activate):接管页面前执行,可清理旧缓存
- fetch 事件监听:拦截网络请求,实现智能缓存策略
常用缓存策略及实现方式
根据不同资源类型选择合适策略,平衡速度与更新及时性。
1. 缓存优先(Cache First),适合静态资源
优先读取缓存,无则请求网络,并将响应加入缓存。
self.addEventListener('fetch', event => { if (event.request.destination === 'image') { event.respondWith( caches.match(event.request).then(cached => { return cached || fetch(event.request).then(response => { const cacheCopy = response.clone(); caches.open('image-cache').then(cache => { cache.put(event.request, cacheCopy); }); return response; }); }) ); } });
2. 网络优先(Network First),适合动态内容
优先尝试网络请求,失败时使用缓存兜底。
self.addEventListener('fetch', event => { if (event.request.url.includes('/api/')) { event.respondWith( fetch(event.request).catch(() => caches.match(event.request) ) ); } });
3. 先缓存后更新(Stale-While-Revalidate)
立即返回缓存内容,同时发起网络请求更新缓存。
self.addEventListener('fetch', event => { event.respondWith( caches.match(event.request).then(cached => { const networkFetch = fetch(event.request).then(response => { if (response.ok) { caches.open('dynamic-cache').then(cache => { cache.put(event.request, response.clone()); }); } return response; }).catch(() => cached); return cached || networkFetch; }) ); });
管理缓存版本与清理旧数据
避免缓存无限增长,安装阶段预加载新资源,激活阶段清除过期缓存。
const CACHE_NAME = 'v2'; const PRECACHE_URLS = ['/offline.html', '/style.css']; self.addEventListener('install', event => { event.waitUntil( caches.open(CACHE_NAME).then(cache => cache.addAll(PRECACHE_URLS)) ); }); self.addEventListener('activate', event => { event.waitUntil( caches.keys().then(keys => { return Promise.all( keys.filter(key => key !== CACHE_NAME) .map(key => caches.delete(key)) ); }) ); });
基本上就这些。合理组合策略,配合缓存命名和版本控制,就能实现灵活可靠的资源管理。注意只对 HTTPS 站点或本地开发环境使用 Service Worker,否则无法注册成功。


