如何实现 0 毫秒无感页面跳转?聊聊被低估的 Speculation Rules API
我们花了整整十年的时间用各种复杂的单页面应用SPA框架、客户端路由预加载、以及冗长的动态import分包试图让网页的跳转看起来像原生App一样瞬间呈现。甚至在Next.js或者Nuxt.js这样的现代框架里我们默认信任它们的动态预取机制Prefetching哪怕这会经常把浏览器的网络面板塞满成百上千个小 JS 分片耗费大量的用户带宽。但在这个行当敲了快十年的代码看了太多为了体感速度而拼命堆砌的复杂基建。我发现很多团队都在无脑跟风做过度设计却忽略了浏览器原生技术里最强大的 API。今天聊聊一个在 2026 年已经被主流浏览器原生支持、被严重低估的Web 标准——Speculation Rules API猜测规则 API。它不需要你写一行繁琐的客户端路由逻辑直接利用浏览器的闲置算力实现物理意义上绝对的0毫秒无感秒开。1. 0 毫秒秒开的底层原理在聊它之前我们得先厘清两个概念预取Prefetch和预渲染Prerender。传统的link relprefetch只是把下一页的HTML静态资源提前下载到本地缓存里。当你点击跳转时浏览器依然要走一遍解析 HTML - 下载并执行 JS - 计算布局 - 绘制页面的完整生命周期。虽然快了但依然有肉眼可见的白屏时间。而Speculation Rules API里的预渲染Prerender走得远比你想的要极端。当你定义了规则后浏览器会在后台直接开启一个隐形的标签页Invisible Tab把目标页面完整地跑一遍下载所有的子资源、执行所有的JS、甚至连DOM 树和页面布局Layout都直接在后台算好。当用户真正点下链接的一瞬间浏览器直接把这个在后台已经渲染好的页面展到屏幕上。大家可以通过在浏览器控制台输入这行命令可以清晰地看到这个物理秒开的铁证// 如果这个值大于 0说明页面是 0 毫秒闪现出来的它来自浏览器的后台预渲染console.log(performance.getEntriesByType(navigation)[0].activationStart);怎么用别再傻傻写死 URL 了很多网上的早期教程只教了最基础的静态列表写法写死一个URL 数组。但在真实的动态业务里你根本不可能预测用户下一个要点哪个商品。现代Speculation Rules API最强大的地方在于文档规则Document Rules。你可以直接通过CSS 选择器和URL 正则模式让浏览器智能地去猜用户的意图。!-- 直接嵌入到 HTML 的极简配置 --scripttypespeculationrules{prerender:[{source:document,where:{and:[{href_matches:/products/*},// 只预渲染商品详情页{not:{href_matches:/products/cart}},// 排除购物车等敏感页面{selector_matches:a.product-link}// 只针对特定类名的链接生效]},eagerness:moderate// 触发时机}]}/script注意里面这个极其关键的参数eagerness饥渴度/触发时机。它有四个档位代表了你对性能和带宽的权衡conservative保守只有在用户按下鼠标mousedown或按住触屏的一瞬间才触发。这给浏览器留了大约 100~200ms 的空档期虽然时间短但绝对不会浪费用户流量。moderate温和当用户鼠标悬停hover在链接上超过 200ms或者在移动端滑过链接时触发。这是绝大多数中后台和独立站的黄金平衡点。eager热切只要链接进入视口Viewport或者一加载就疯狂预渲染。除非你对服务器带宽非常有自信且用户全在宽带环境下否则别轻易用。必坑指南隐藏在 0ms 后的三个致命问题写出上面的配置任何一个刚毕业的开发自学半天也能搞定。但如果直接上线你大概率会亲手制造一起线上事故。我给你盘盘这三个连大厂开发都经常翻车的细节。1.流量与统计污染Analytics Double-Fire因为预渲染是在后台静默执行了完整的JS逻辑这就意味着如果你的数据埋点如 Google Analytics、自研神策系统写在组件的mounted阶段它会在用户还没点击页面时就直接上报一次 PageView。这会导致你们公司的业务转化率、UV 统计直接出现灾难性的偏差。破局方法可以利用document.prerendering进行埋点拦截// 防范静默预渲染导致的统计污染functiontrackPageView(){if(document.prerendering){// 如果当前处于后台静默渲染阶段绝对不上报// 而是注册事件等待用户真正点击激活页面后再触发document.addEventListener(prerenderingchange,(){sendTelemetry();// 真正展现给用户时才发送打点},{once:true});}else{// 正常跳转直接上报sendTelemetry();}}2.状态滞后与库存脏数据设想一下用户在列表页 A 浏览浏览器在后台静默预渲染了详情页 B。此时用户在 A 页面把商品加入了购物车。然后点击进入 B 页面。因为 B 页面是在几分钟前就在后台渲染好的它里面的购物车数量、甚至库存状态依然保留着几分钟前的旧数据。可以先检测激活状态动态更新脏数据// 检测页面是否是通过激活无感跳转进来的constnavEntryperformance.getEntriesByType(navigation)[0];if(navEntrynavEntry.activationStart0){// 说明这个页面是在后台加载过的我们需要局部刷新那些易变的状态refreshCartCount();refreshInventoryStatus();}3.破坏单例与服务端压力雪崩如果你的页面有复杂的动态API请求比如一进页面就拉取个性化推荐。一旦你开启了eager或者moderate预渲染意味着用户每次滑动屏幕你的服务器都会承受数倍于平时的 API 请求压力。对于小团队来说这会直接把你们脆弱的Node服务端或者云数据库打挂。所以核心业务如支付、下单严禁开启prerender最多只能开启轻量级的prefetch只下HTML不执行JS。4.浏览器兼容性到目前2026年5月主流浏览器已经开始支持新特性。但是Safari浏览器还没得到支持。大家选择的时候还是得谨慎 (当然对于不支持的浏览器可以使用其它回退方案)让浏览器干它该干的事在过去咱们为了提速在React/Vue路由里写了成百上千行的预加载逻辑把工程搞得无比臃肿还要时刻提防主线程卡顿。但历史的规律一直在证明任何在框架层拼命挣扎的复杂基建最终都会被 Web 原生标准降维打击。Speculation Rules API的出现我们只需要给出一份轻量级的JSON 配置剩下的多线程调度、带宽节流、安全沙盒隔离全部交由C编写的底层引擎去搞定, 后面的事情 咱们就不用操心。把精力放回到真正的业务逻辑和边界防御上。用最轻量的原生标准给用户换来极致的、物理意义上的秒开体验。分享完毕