你以为 SW 加缓存能让导航变快?今天 Chrome 把这件事用零代码彻底原生化了

做过一次 SW 缓存优化的工程师,大概都踩过这个坑——满怀期待给网站加上了 ServiceWorker,想着这下导航总该快了吧。结果一测,慢了 200 毫秒。

这不是你配错了。这是 SW 本身的问题:浏览器每次导航请求都要等 SW 启动完毕,才能进 fetch handler。而 SW 的启动本身,在最坏情况下可以花掉几百毫秒——跟网络耗时一样量级。你以为缓存帮你省了网络,结果启动延迟把省出来的时间全贴回去了。

Chrome 154(2026 年 9 月 9 日正式版)对这件事给出了一个零代码答案:ServiceWorkerAutoPreload。

旧世界:SW 启动和导航请求串行

没有这个功能的时候,浏览器处理一次带 SW 的导航请求,是这样的:

  1. 浏览器发起导航,命中 SW 管辖范围
  2. SW 还没启动,浏览器等 SW bootstrap 完成
  3. SW 启动后,fetch handler 才被调用
  4. fetch handler 里才决定是从缓存返回还是发网络请求
  5. 用户看到页面内容

第 2 步的等待时间,在低端机上可以轻松超过 200ms。你的 SW 缓存配得再漂亮,这一百多毫秒也省不掉。

新世界:导航请求和 SW 启动并行

ServiceWorkerAutoPreload 做的事情很简单:把第 3 步的网络请求提前到第 2 步,和 SW bootstrap 同时发出。

旧:SW启动 ────→ fetch handler ────→ 网络请求
新:SW启动 ────→ fetch handler
     ↓
     网络请求(并行!)

fetch handler 里的 fetch(event.request) 会直接消费这个提前发出的请求,不需要再等 SW 启动完再发。响应一致性完全保留:fetch handler 仍然有最终决定权,如果它返回自定义 Response,预加载的请求会被丢弃,不会有任何副作用。

这个行为相当于自动版的 NavigationPreload。但 NavigationPreload 需要你在 SW 里多写一行 registration.navigationPreload.enable(),而 ServiceWorkerAutoPreload 什么都不用改。

它会影响哪些页面

根据 Chrome 统计,ServiceWorker 参与了约 15% 的页面加载。这个功能目前以 stepped rollout 方式随 Chrome 154 推送,正式稳定版预计 2026 年 9 月 9 日发布。Chrome 154 也是 Chrome 切换为双周发布周期后的第一个版本。

你不需要做任何事情

这是它真正有价值的地方:功能默认开启,不需要在 SW 里写任何代码,也不需要在服务器端做任何配置。如果你的 fetch handler 里用的是标准的 fetch(event.request) 模式,Chrome 会自动对这个请求做并行优化。如果 fetch handler 返回的是自定义 Response(比如 new Response(“cached”)),预加载的请求会被静默丢弃,不影响任何行为。

如果你需要关闭它,Chrome 企业策略里有一个 ServiceWorkerAutoPreloadEnabled 开关可以禁用。但对大多数开发者来说,这个功能完全是透明的。

还有一件事:Chrome 发布周期变了

Chrome 154 开始,Chrome 从每四周发布一个稳定版切换为每两周一个稳定版。ServiceWorkerAutoPreload 本身在 M154 之后也会从策略里移除(它是临时管控机制),因为它最终会直接进入默认行为。双周发布意味着这类性能改进会更频繁地到达用户侧,代价是你需要让自己的测试流程跟上更快的版本节奏。


你的网站现在有 ServiceWorker 吗?不妨打开 Chrome DevTools 的 Network 面板,看一下带 SW 拦截的导航请求,Request Start 到 Response Start 之间有多少毫秒。然后等 Chrome 154 覆盖到你用户的时候,再测一遍。

评论区

0 条评论

登录后可评论。

阿速·性能优化 259 阅读