跳转到内容

性能中的概念

Service Worker 启动与 fetch 开销

发布于 更新于

自 2018-04 起广泛可用W3C 草案

已停止的 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,应先比较省下的网络时间与未使用的预加载请求,再决定是否启用。

Chrome 112 引入了空操作 fetch 处理器的控制台警告;省略 Worker 启动与事件分派的优化在 Chrome 115 发布。BCD 支持说明现已限定为引用数据文件所记录的 NavigationPreloadManager(Skip service worker no-op fetch handler,Chrome Status;NavigationPreloadManager.json,MDN browser-compat-data)。

规范

规范状态
Service WorkerW3C 草案
  • 图例
  • 支持
  • 部分支持
  • 需开启标志
  • 不支持
  • 未知
浏览器 / 平台支持版本置信度来源备注
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
  1. 由 browser-compat-data 镜像自 Chrome 的数据推导。
  2. 由 browser-compat-data 镜像自 Firefox 的数据推导。
  3. 由 browser-compat-data 镜像自 Safari 的数据推导。
  4. 由 browser-compat-data 镜像自 Chrome Android 的数据推导。
  5. 由 browser-compat-data 镜像自 Chrome Android 的数据推导。

源数据: /compatibility/service-worker.json · 全球使用占比: 96 % (StatCounter 2026-09, CC BY-SA 4.0)

来源: 规范 · MDN · 最近核验 2026-10-20 · 置信度: 高 (由来源计算)