Service Worker 是 PWA 离线访问核心,需通过 HTTPS 注册、预缓存关键资源、分层缓存策略(Precache/ Runtime Cache)、离线兜底响应、主动更新与调试。

Service Worker 是 PWA 实现离线访问的核心机制,它本质是一个可拦截网络请求、管理缓存并控制页面加载行为的脚本。要让应用真正“离线可用”,关键不是简单注册 Service Worker,而是合理设计缓存策略、预缓存关键资源,并正确处理动态请求的回退逻辑。
注册与安装:确保 Service Worker 被正确加载
Service Worker 必须通过 HTTPS(本地 localhost 除外)运行,且注册代码需放在主页面的 JavaScript 中(如 main.js 或内联脚本):
- 调用 navigator.serviceWorker.register('/sw.js') 启动注册,路径必须是根相对路径(如 /sw.js),否则作用域受限
- 在 install 事件中使用 cache.addAll() 预缓存 HTML、CSS、JS、图标等核心静态资源(即“Shell”)
- 调用 event.waitUntil() 确保安装完成前不终止,避免缓存不全导致离线失败
缓存策略:区分静态资源与动态内容
单一缓存策略无法兼顾性能与一致性。推荐分层处理:
- 预缓存(Precache):安装阶段缓存已知不变的资源(如 index.html、app.js),版本更新时自动替换旧缓存
- 运行时缓存(Runtime Cache):在 fetch 事件中拦截请求,对 API 接口用 Network First(优先联网,失败则 fallback 到缓存或占位页),对图片等大资源用 Cache First(先查缓存,未命中再请求)
- 避免缓存 HTML 页面本身(除非是纯静态页),否则用户可能看不到新内容;改用 Stale-While-Revalidate 模式:返回缓存 HTML 同时后台刷新
离线兜底:提供可用的用户体验
用户断网时,不能只显示浏览器默认错误页。应在 fetch 事件中主动响应:
- 对导航请求(request.destination === 'document'),若缓存中无匹配 HTML,返回预置的 offline.html(需提前缓存)
- 对 API 请求,可返回模拟数据、空数组或带提示的 JSON(如 { error: "offline", message: "当前网络不可用" })
- 在页面中监听 navigator.onLine 变化,配合 UI 提示(如顶部横幅),并自动重试待发请求
更新与调试:避免缓存陈旧导致问题
Service Worker 更新机制较隐蔽,容易卡在“waiting”状态:
- 每次修改 sw.js 文件内容(哪怕加个空格),浏览器才会触发新版本安装流程
- 调用 self.skipWaiting() 在 install 阶段跳过 waiting,使新 SW 立即激活(适合非破坏性更新)
- 使用 Chrome DevTools 的 Application → Service Workers 面板:勾选 “Update on reload”、点击 “Skip waiting” 或 “Unregister” 手动调试
- 在 fetch 中添加 console.log 并查看 “Console” 标签页输出,确认请求是否被拦截——这是验证 SW 是否生效最直接的方式

















