Service Worker 生命周期详解
Service Worker 的生命周期是理解其工作原理的核心,包含以下关键阶段:
1. 注册阶段(Registration)
javascript// 在主线程中注册 if ('serviceWorker' in navigator) { navigator.serviceWorker.register('/sw.js') .then(registration => { console.log('SW registered:', registration); }) .catch(error => { console.log('SW registration failed:', error); }); }
2. 安装阶段(Installation)
- 浏览器下载 Service Worker 脚本
- 触发
install事件 - 适合进行静态资源的预缓存
javascriptself.addEventListener('install', event => { event.waitUntil( caches.open('v1').then(cache => { return cache.addAll([ '/', '/styles.css', '/app.js' ]); }) ); // 立即激活新的 Service Worker self.skipWaiting(); });
3. 等待阶段(Waiting)
- 新的 Service Worker 安装完成后进入等待状态
- 等待旧的 Service Worker 控制的所有页面关闭
- 可以通过
skipWaiting()跳过等待
4. 激活阶段(Activation)
- 旧的 Service Worker 被替换后触发
activate事件 - 适合清理旧缓存
- 此时 Service Worker 开始控制页面
javascriptself.addEventListener('activate', event => { event.waitUntil( caches.keys().then(cacheNames => { return Promise.all( cacheNames .filter(name => name !== 'v1') .map(name => caches.delete(name)) ); }) ); // 立即接管页面 self.clients.claim(); });
5. 运行阶段(Running/Idle)
- 监听
fetch、push、sync等事件 - 处理网络请求和后台任务
- 浏览器可能随时终止 Service Worker 以节省资源
6. 终止阶段(Termination)
- 浏览器自动回收资源
- 下次事件触发时重新启动
- 保持状态不丢失(但全局变量会重置)
状态转换图
shell注册 → 下载 → 安装中 → 安装完成 → 等待中 → 激活中 → 激活完成 → 空闲/运行 ↓ 被新 SW 替换
最佳实践
- 版本管理:使用版本号管理缓存(如 'v1', 'v2')
- 优雅升级:通过页面刷新触发新 Service Worker 激活
- 缓存清理:在 activate 阶段清理过期缓存
- 错误处理:每个阶段都要添加适当的错误处理