Service Worker 是什么
Service Worker 是浏览器在后台运行的脚本,独立于网页。它是浏览器和网络之间的代理,可以:
- 拦截网络请求
- 缓存资源
- 推送通知
- 后台同步
与其他 Worker 的区别
- Web Worker:在后台线程运行脚本,不阻塞主线程
- Service Worker:在浏览器幕后运行,可以拦截网络请求
Service Worker 的生命周期
Installing → Installed → Activating → Activated → Redundant
1. Installing
// sw.js
const CACHE_NAME = 'v1';
self.addEventListener('install', event => {
console.log('SW Installing');
// 缓存静态资源
event.waitUntil(
caches.open(CACHE_NAME).then(cache => {
return cache.addAll([
'/',
'/styles.css',
'/script.js'
]);
})
);
});
2. Activating
self.addEventListener('activate', event => {
console.log('SW Activating');
// 清理旧缓存
event.waitUntil(
caches.keys().then(cacheNames => {
return Promise.all(
cacheNames
.filter(name => name !== CACHE_NAME)
.map(name => caches.delete(name))
);
})
);
});
3. Fetch
self.addEventListener('fetch', event => {
event.respondWith(
caches.match(event.request).then(response => {
return response || fetch(event.request);
})
);
});
常用缓存策略
策略一:Cache First(缓存优先)
适合静态资源(CSS、JS、图片):
self.addEventListener('fetch', event => {
event.respondWith(
caches.match(event.request).then(response => {
return response || fetch(event.request);
})
);
});
策略二:Network First(网络优先)
适合 API 数据:
self.addEventListener('fetch', event => {
event.respondWith(
fetch(event.request)
.then(response => {
// 缓存新内容
const clone = response.clone();
caches.open(CACHE_NAME).then(cache => {
cache.put(event.request, clone);
});
return response;
})
.catch(() => {
// 网络失败时用缓存
return caches.match(event.request);
})
);
});
策略三:Stale While Revalidate
先返回缓存,同时在后台更新缓存:
self.addEventListener('fetch', event => {
event.respondWith(
caches.open(CACHE_NAME).then(cache => {
return cache.match(event.request).then(response => {
// 发起新请求更新缓存
const fetchPromise = fetch(event.request).then(networkResponse => {
cache.put(event.request, networkResponse.clone());
return networkResponse;
});
// 返回缓存或等待新内容
return response || fetchPromise;
});
})
);
});
PWA 离线应用
注册 Service Worker
// main.js
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw.js')
.then(reg => console.log('SW registered', reg))
.catch(err => console.error('SW registration failed', err));
}
Web App Manifest
// manifest.json
{
"name": "My PWA",
"short_name": "MyApp",
"start_url": "/",
"display": "standalone",
"background_color": "#ffffff",
"icons": [
{ "src": "/icon-192.png", "sizes": "192x192", "type": "image/png" },
{ "src": "/icon-512.png", "sizes": "512x512", "type": "image/png" }
]
}
这一章想说的
Service Worker 是 PWA 的核心技术:
- 生命周期:Installing → Activating → Fetch
- 缓存策略:Cache First、Network First、Stale While Revalidate
- 离线能力:配合 Cache Storage 实现完整离线应用
Service Worker 让 Web 应用可以像原生应用一样离线使用、推送通知。