性能中的概念
Service Worker 启动与 fetch 开销
发布于 更新于
已停止的 Service Worker 必须先启动,才能运行 fetch 处理器。如果处理器随后访问网络,启动和处理器执行会发生在网络请求之前;导航预加载可以让导航请求与 Worker 启动并行(Service worker deployment,Chrome for Developers)。
BCD 记录 NavigationPreloadManager 从 Chrome 59、Edge 18、Firefox 99 和 Safari 15.4 起得到支持;该 API 可缓解这里所述的启动开销(NavigationPreloadManager.json,MDN browser-compat-data)。
工作原理
链接到“工作原理”一节浏览器会在 Service Worker 进程不活跃时停止它,并在需要分派事件时启动它。因此,进入 fetch 处理器的受控导航要等待已停止的 Worker 启动。缓存响应可以抵消这项成本;调用 fetch(event.request) 的透传处理器仍需执行网络工作,并在此之前增加 Worker 路径(Service worker deployment,Chrome for Developers)。
Navigation Timing 暴露 workerStart,表示请求开始由 Worker 处理的时点。页面不受 Service Worker 控制时,该值为 0。Chrome DevTools 在 Network 面板的 Timing 标签中把对应的请求阶段标为 ServiceWorker Preparation 和 Request to ServiceWorker(Network features reference,Chrome for Developers)。
导航预加载作用于导航请求。在注册上启用后,浏览器可以在 Worker 启动时开始网络请求,处理器通过 event.preloadResponse 读取该响应。它不会移除其他处理器逻辑的执行成本;处理器从缓存响应时,它还可能浪费一次请求。
先在页面中测量启动,再只对依赖网络的导航使用预加载。
测量受控导航
链接到“测量受控导航”一节回退分支报告这次导航没有 Service Worker 时序,而不是拿值为零的哨兵做减法。
const [navigation] = performance.getEntriesByType('navigation');
if (!navigation || navigation.workerStart === 0) { console.log('This navigation has no service worker timing.');} else { const beforeWorker = navigation.workerStart - navigation.startTime; const workerToRequest = navigation.requestStart - navigation.workerStart; console.table({ beforeWorker, workerToRequest });}应在真实设备上收集这些字段。部署指南指出,启动时间随设备能力和 CPU 压力变化,因此单台开发机器上的值不能作为通用预算。
让启动与导航请求重叠
链接到“让启动与导航请求重叠”一节激活期间检测注册是否暴露预加载,再启用它。fetch 处理器使用预加载响应;预加载不存在或没有产生响应时,回退到普通 fetch。
self.addEventListener('activate', (event) => { if (!('navigationPreload' in self.registration)) return; event.waitUntil(self.registration.navigationPreload.enable());});
self.addEventListener('fetch', (event) => { if (event.request.mode !== 'navigate') return;
event.respondWith((async () => { const preloaded = await event.preloadResponse; if (preloaded) return preloaded; return fetch(event.request); })());});如果导航通常来自 Cache Storage,应先比较省下的网络时间与未使用的预加载请求,再决定是否启用。
更正(2026-10-23)
链接到“更正(2026-10-23)”一节Chrome 112 引入了空操作 fetch 处理器的控制台警告;省略 Worker 启动与事件分派的优化在 Chrome 115 发布。BCD 支持说明现已限定为引用数据文件所记录的 NavigationPreloadManager(Skip service worker no-op fetch handler,Chrome Status;NavigationPreloadManager.json,MDN browser-compat-data)。
另请参阅
链接到“另请参阅”一节- 导航预加载与 Service Worker 启动时间
- Service Worker 静态路由 API
- Service Worker 缓存策略
- Speed up service worker with navigation preloads(web.dev)
- Network features reference(Chrome for Developers)
规范
| 规范 | 状态 |
|---|---|
| Service Worker | W3C 草案 |
- 图例
- 支持
- 部分支持
- 需开启标志
- 不支持
- 未知
| 浏览器 / 平台 | 支持 | 版本 | 置信度 | 来源 | 备注 |
|---|---|---|---|---|---|
| Chrome (Desktop)# | 支持 | 40 | 高 | 来源 | — |
| Chrome (Android)# | 支持 | 40 | 高 | 来源 | 1 |
| Edge (Desktop)# | 支持 | 17 | 高 | 来源 | — |
| Firefox (Desktop)# | 支持 | 44 | 高 | 来源 | — |
| Firefox (Android)# | 支持 | 44 | 高 | 来源 | 2 |
| Safari (macOS)# | 支持 | 11.1 | 高 | 来源 | — |
| Safari (iOS)# | 支持 | 11.3 | 高 | 来源 | 3 |
| Samsung Internet# | 支持 | 4.0 | 高 | 来源 | 4 |
| WebView (Android)# | 支持 | 40 | 高 | 来源 | 5 |
- 由 browser-compat-data 镜像自 Chrome 的数据推导。
- 由 browser-compat-data 镜像自 Firefox 的数据推导。
- 由 browser-compat-data 镜像自 Safari 的数据推导。
- 由 browser-compat-data 镜像自 Chrome Android 的数据推导。
- 由 browser-compat-data 镜像自 Chrome Android 的数据推导。