Service worker 调试
一句话: Chrome DevTools 的应用面板(以及 Firefox 和 Safari 的等效面板)让你无需部署任何改动,即可检查注册状态、强制更新、测试离线、清空缓存,并观察 fetch 事件的拦截情况。
Chrome DevTools
Section titled “Chrome DevTools”应用 → Service Workers
Section titled “应用 → Service Workers”主要的调试界面。打开 DevTools → 应用 → Service Workers(左侧边栏)。
| 控件 | 作用 |
|---|---|
| 重新加载时更新 | 每次导航都强制进行字节比较并安装新 worker |
| 绕过网络 | 为此标签页禁用 service worker——所有 fetch 事件直接透传 |
| 离线 | 模拟无网络状态(针对经过 service worker 的请求) |
| 更新 | 手动触发 registration.update() |
| 取消注册 | 彻底移除注册 |
面板还显示当前状态:正在安装、等待中或已激活——以及脚本 URL 和 scope。
强制更新 worker
Section titled “强制更新 worker”开发阶段,“重新加载时更新”复选框是测试 worker 改动最快捷的方式。若不勾选,Chrome 最长会在 24 小时内使用缓存的 worker 脚本,即使文件已更改,浏览器也只在检测到字节差异时才安装新 worker。
若新 worker 卡在 waiting 状态,面板会显示“skipWaiting”链接,点击即可立即对待激活的 worker 调用 skipWaiting()——无需修改 worker 代码即可测试。
Cache Storage
Section titled “Cache Storage”DevTools → 应用 → Cache Storage 列出所有具名缓存及其条目。你可以查看请求/响应头、预览响应体,以及删除单个条目或整个缓存。
检查 fetch 事件
Section titled “检查 fetch 事件”打开 Network 面板,启用 Service Worker 列(右键单击列标题)。每个请求都会显示是否由 service worker 提供,以及来自缓存还是网络。“大小”列中的 (ServiceWorker) 标签确认 worker 拦截了该请求。
在 worker 上下文中使用控制台
Section titled “在 worker 上下文中使用控制台”将 DevTools 控制台的 JavaScript 上下文(过滤栏旁的下拉菜单)从“top”切换为 service worker URL。worker 内部的 console.log 调用会出现在这个上下文中。
你还可以在 worker 的全局作用域中运行表达式,包括检查 self.registration、caches.keys() 和 self.clients.matchAll()。
Firefox DevTools
Section titled “Firefox DevTools”打开 about:debugging#/runtime/this-firefox → “此 Firefox” → “Service Workers”。Firefox 列出每个已注册的 worker,显示其 scope、状态和 检查 链接,点击后会打开该 worker 的专用控制台。
Firefox 没有内置的“重新加载时更新”复选框。开发时若要强制重新安装,可取消注册 worker 后刷新,或在页面控制台中调用 registration.update()。
Safari Web Inspector
Section titled “Safari Web Inspector”在 Safari(iOS 或 macOS)中,开启开发菜单(偏好设置 → 高级 → 在菜单栏中显示“开发”菜单)。打开 Web Inspector → 存储 → Service Workers。Safari 列出已注册的 worker、其 scope 和脚本 URL。
Safari Web Inspector 的调试能力比 Chrome 或 Firefox 有限:没有专用的缓存查看器或“强制更新”复选框。可在 worker 上下文的控制台中使用 caches.keys() 进行检查。
常见问题诊断
Section titled “常见问题诊断”| 症状 | 可能原因 | 解决方案 |
|---|---|---|
| Worker 卡在 waiting | 旧标签页未关闭且未调用 skipWaiting() |
关闭所有标签页,或使用 DevTools 的“skipWaiting”链接 |
| 部署后新代码未运行 | HTTP 缓存提供了旧 worker 脚本 | 使用 updateViaCache: 'none' 或为 worker URL 设置 Cache-Control: no-cache |
| 请求未被拦截 | Worker 尚未激活(仍在安装中)或 scope 不匹配 | 在 DevTools 中检查 scope;激活后重新加载 |
| 缓存未填充 | install 失败或未调用 event.waitUntil() |
在 worker 上下文控制台中检查是否有错误 |
| 提供了过期内容 | CacheFirst 策略没有设置过期 |
添加 ExpirationPlugin 或为缓存名称加版本号 |
| 未显示离线兜底页面 | 兜底页面未在 install 中预缓存,或 fetch 事件判断条件有误 |
检查 Cache Storage 中是否有兜底 URL;添加日志 |
Workbox 日志
Section titled “Workbox 日志”Workbox 在开发构建中会输出详细日志。调试时切换到 Workbox 的开发版本:
import { setCacheNameDetails } from 'workbox-core';// 开发版本会在控制台打印策略决策日志当 process.env.NODE_ENV !== 'production' 时,Workbox 会自动选择开发构建。
- 开发期间在 DevTools 中启用“重新加载时更新”,避免 worker 缓存造成混乱。
- 切换到 worker 控制台上下文,查看 worker 端的
console.log输出。 - 需要临时跳过 service worker 测试时,使用“绕过网络”。
- 部署后确认 Cache Storage 中只有新版本缓存,旧缓存已被删除。
- 在 DevTools Network 中勾选“离线”并导航到未缓存的 URL 来测试离线兜底。
- 更新流程与 skipWaiting — 理解 worker 为何卡在 waiting 状态
- 缓存策略 — Cache Storage 中可见的各种策略
- 注册与 scope — Service Workers 面板中可见的 scope 问题