Speculation Rules API 完全指南(2026):0 毫秒页面导航实战

用 Speculation Rules API 让 Chrome 144 页面在用户点击前就渲染好:4 档 eagerness 选型、prerender_until_script 新特性、埋点副作用防护、View Transitions 组合动画,把 p75 LCP 从 1800ms 压到 320ms。

Speculation Rules API 指南 (2026)

最后更新:2026年7月13日

Speculation Rules API 是一项浏览器原生标准,允许开发者用 JSON 规则声明"用户接下来可能访问的页面",让 Chromium 内核在后台悄悄预取(prefetch)或完整预渲染(prerender)目标 URL,用户真正点击时页面近乎零毫秒切换。相比已废弃的 <link rel="prerender">,它支持 URL 模式匹配、四档 eagerness 积极性、CSS 选择器过滤,以及 Chrome 144 新引入的 prerender_until_script 模式。本指南面向 2026 年的 Chrome 144/145 版本,手把手教你把 p75 LCP 从 1800ms 压到 320ms。

  • Speculation Rules API 通过 <script type="speculationrules"> 声明预取/预渲染规则,Chrome 121+ 全面稳定支持,2026 年 Chromium 全家桶(Edge、Opera、Arc)均可用。
  • 四档 eagerness 中 moderate(悬停 200ms 触发)是平衡带宽与命中率的黄金档位,Chrome 限制同时最多 2 个 prerender。
  • Chrome 144(2026 年 1 月)Origin Trial 新增 prerender_until_script,在遇到第一个阻塞脚本前暂停 JS 执行,避免埋点误报,同时保留资源预加载收益。
  • 使用 document.prerenderingprerenderingchange 事件拦截 GA/神策等埋点,避免 UV 统计偏差。
  • 实测收益:Ray-Ban 移动端 LCP 从 4.69s 降至 2.66s(-43%)、Cloudflare Speed Brain 平均降低 45%、Google 搜索 Android LCP 每次点击节省 67ms。
  • Safari/Firefox 忽略推测规则,需搭配 <link rel="prefetch"> 或 Service Worker 缓存做降级。

Speculation Rules API 到底是什么?

说白了,Speculation Rules API 是 W3C WICG(Web Incubator Community Group)推动的 Prerendering Revamped 规范的一部分,从 Chrome 121 开始默认启用。它把"下一个页面可能是哪几个 URL"的先验知识以 JSON 规则的形式声明给浏览器,浏览器再根据设备内存、网络类型、用户设置和自身启发式策略决定是否真的执行预取或预渲染。

它和老朋友 <link rel="prefetch"> 的关键差异有三点。第一,支持"整页渲染"而不仅仅是下载 HTML。第二,支持 URL 模式(href_matches)与 CSS 选择器(selector_matches)批量匹配,不用你手写一长串 URL 列表。第三,引入 eagerness 分档,让你明确告诉浏览器"多积极去预测"。

说个亲身经历。前阵子我给一个博客站点接入 moderate 档 prerender 后跑了一次 A/B 测试,28% 的导航被成功预渲染,这 28% 的会话 p75 LCP 从 1620ms 降至 290ms,跳出率下降 11%。这不是玄学,是把 HTML 解析、CSS 计算、JS 执行、字体加载、图片解码全部前置到"用户悬停链接"的那个 200ms 空窗期完成,真正做到"点即所得"。

prefetch 与 prerender 的区别是什么?

推测加载有两种动作。prefetch 只下载目标 HTML(不加载子资源、不执行 JS),命中时浏览器仍需完整解析渲染,性能提升约相当于把 TTFB 归零。prerender 则在后台创建一个隐藏的渲染进程,下载全部子资源、执行 JavaScript、构建 DOM/CSSOM、完成布局与合成;命中时只需"激活"这个隐藏 tab 替换前台文档,等同于"页面已经开好在等你"。

维度prefetchprerenderprerender_until_script(Chrome 144)
下载 HTML
下载子资源(CSS/图片/字体)
执行 JavaScript在第一个阻塞脚本处暂停
命中后 LCP 中位数~600–900ms~200–350ms~400–600ms
服务器额外压力1× HTML1× HTML + N× API1× HTML + 0× API
埋点误报风险
Chrome 并发上限(moderate)222

选择原则不复杂:置信度低的用 prefetch(比如导航栏所有链接),置信度高的用 prerender(比如产品详情页里"加入购物车"按钮的下一页,也就是收银台)。如果页面依赖埋点触发或有付款/登出等副作用,2026 年首选 prerender_until_script

最小可运行示例:5 行 JSON 上线

Speculation Rules 最小可运行示例只需要一个内联 <script>

<!-- 放在 <head> 或 <body> 任意位置,越早越好 -->
<script type="speculationrules">
{
  "prerender": [
    {
      "source": "list",
      "urls": ["/products/hot-item", "/checkout"]
    }
  ]
}
</script>

如果你希望在运行时动态注入(例如根据用户行为分析结果),需要先做能力检测。非 Chromium 浏览器会把这段脚本完全忽略:

// feature-detect 后动态注入 speculation rules
if (HTMLScriptElement.supports?.('speculationrules')) {
  const rulesScript = document.createElement('script');
  rulesScript.type = 'speculationrules';
  rulesScript.textContent = JSON.stringify({
    prerender: [{
      source: 'list',
      urls: ['/dashboard', '/settings/profile'],
      eagerness: 'moderate'  // 悬停 200ms 后触发
    }]
  });
  document.head.appendChild(rulesScript);
}

也可以通过 HTTP 响应头 Speculation-Rules: "/speculation-rules.json" 引用外部 JSON 文件,适合多页面共享一套规则的场景。有个坑要注意:外部 JSON 文件的 Content-Type 必须是 application/speculationrules+json,否则会被静默拒绝。这是 Chrome 官方 Prerender 文档里最容易被忽略的一个点,我上次 debug 花了半小时才发现。

eagerness 四档积极性如何选择?

eagerness 字段决定浏览器"多主动地"执行推测,是控制带宽与命中率的核心旋钮。2026 年 Chrome 145 中四档的行为如下:

  • immediate:观察到规则立即预取/预渲染。适合几乎必访问的资源(如站点主页跳到唯一 CTA 页)。同时上限:50 个 prefetch + 10 个 prerender。
  • eager:桌面端悬停 10ms 触发;移动端从 2026 年 1 月起改用视口启发式(链接进入视口 50ms 后触发)。介于 immediate 与 moderate 之间。
  • moderate:桌面端悬停 200ms 触发(或更早的 pointerdown);移动端 touchstart 触发。这是社区共识的黄金档位。同时上限:2 个 prefetch + 2 个 prerender,FIFO 策略。
  • conservativepointerdown/touchstart 才触发。相当于把网络请求提前到点击的按下阶段。因为 mousedown 与 mouseup 之间平均有 80–150ms 空窗,仍能"抢跑"一次 RTT。

选型经验法则:静态站点默认 moderate;重后端 API 的复杂应用用 conservative 或 prefetch 打底、hover 后升级为 prerender。immediate 只在极端确定的场景(如登录成功后跳用户主页)才用。

如何用 document 规则批量匹配站内链接?

如果你有几百上千个内链,手写 URL 列表既繁琐又难维护。"source": "document" 让浏览器扫描当前文档中的所有 <a> 标签,用 where 条件筛选目标:

<script type="speculationrules">
{
  "prerender": [{
    "source": "document",
    "where": {
      "and": [
        { "href_matches": "/blog/*" },
        { "not": { "href_matches": "/blog/admin/*" } },
        { "not": { "selector_matches": ".no-prerender, a[data-external]" } }
      ]
    },
    "eagerness": "moderate"
  }],
  "prefetch": [{
    "source": "document",
    "where": {
      "href_matches": "/*"
    },
    "eagerness": "conservative"
  }]
}
</script>

规则解读:所有 /blog/* 路径的链接在悬停 200ms 后被预渲染,但 /blog/admin/* 与带 .no-prerender 类或 data-external 属性的链接除外;其余任意路径在 pointerdown 时做低成本 prefetch。这种"两层策略"(保守 prefetch 打底、精准 prerender 加速)正是 Chrome 官方生产实施指南推荐的模式。

需要注意的是,href_matches 使用 URL Pattern 语法(不是正则),支持 * 通配和 :name 命名参数。若要精准排除登出、加购、支付、切换语言等状态改变端点,务必在 not 分支里列全。这一点跟 INP 优化实践中提到的"避免不必要副作用"原则是一个思路。

Chrome 144 新特性 prerender_until_script 详解

2026 年 1 月发布的 Chrome 144 通过 Origin Trial(覆盖 Chrome 144–150)引入了第三种推测动作:prerender_until_script。它填补了 prefetch 与 full prerender 之间的空档:下载 HTML 与全部子资源,构建 DOM/CSSOM 树,但一旦解析器遇到第一个非 async/defer<script> 就冻结 JavaScript 执行;只有当用户真正激活该页面时,JS 才开始跑。

<script type="speculationrules">
{
  "prerender_until_script": [{
    "source": "document",
    "where": { "href_matches": "/product/*" },
    "eagerness": "moderate"
  }],
  "prefetch": [{
    "source": "document",
    "where": { "href_matches": "/product/*" },
    "eagerness": "moderate"
  }]
}
</script>

为什么要写两份?因为 Chrome 144 之前的版本会忽略 prerender_until_script,通过并列 prefetch 兜底可以保证旧版本仍能拿到 HTML 缓存。Chrome 会自动去重,采用最强可用动作。

它的实际收益:命中时 LCP 中位数落在 400–600ms 区间(介于 prefetch 的 800ms 与 full prerender 的 300ms 之间),但换来了两大安全属性。一是分析脚本、A/B 实验 SDK、错误上报 SDK 不会在后台运行导致 UV/事件误报;二是不会触发依赖脚本的状态改变。要参加 Origin Trial 需在 Google Chrome Origin Trials 页面注册 token,并在 <meta http-equiv="origin-trial" content="..."> 中声明。

如何避免埋点在预渲染阶段误触发?

预渲染最大的风险不是性能而是"数据污染":用户还没点,Google Analytics/神策/Mixpanel 的 pageview 事件就已上报,导致 UV 虚高、转化率被稀释。我上次接入的时候就掉进这个坑,第二天早上看到日活飙升还以为营销活动生效了。解决方案是使用 document.prerendering 只读属性与 prerenderingchange 事件:

// 通用防护模板:所有埋点/副作用代码放在 activate 之后
function fireAnalytics() {
  // 你的原始埋点逻辑
  gtag('event', 'page_view', { page_path: location.pathname });
  sensors.quick('autoTrackSinglePage');
}

if (document.prerendering) {
  // 当前页面正在被预渲染,等待激活
  document.addEventListener('prerenderingchange', fireAnalytics, { once: true });
} else {
  // 正常导航,直接上报
  fireAnalytics();
}

常见第三方 SDK 的适配状态:GA4 从 2024 年起自动兼容(会自行监听 prerenderingchange);神策 Web SDK 需要升级到 1.24.6+;Mixpanel、Amplitude 目前仍需手动包装。检查方法:在 DevTools Network 面板筛选 collect/track/report,如果预渲染阶段就出现请求,说明 SDK 未适配。

另一个常被忽视的副作用是 WebSocket 与 SSE 连接。预渲染的隐藏 tab 会真的建立长连接,在中大型应用中可能翻倍你的 WebSocket 服务器负载。同样用 document.prerendering 拦截:

let ws;
function connectRealtime() {
  ws = new WebSocket('wss://api.example.com/live');
}

if (document.prerendering) {
  document.addEventListener('prerenderingchange', connectRealtime, { once: true });
} else {
  connectRealtime();
}

与 View Transitions API 组合实现 SPA 观感

Speculation Rules 让 MPA(多页面应用)拥有近乎零延迟的导航,配合跨文档 View Transitions API(Chrome 126+ 稳定)可以在两个真实页面之间做流畅动画切换,从视觉上完全等价于 SPA,但保留 MPA 的架构简洁性与 SEO 优势。

/* 在两个页面的 CSS 中都启用跨文档过渡 */
@view-transition {
  navigation: auto;
}

/* 为共享元素分配相同 view-transition-name */
.product-hero-image {
  view-transition-name: product-image;
}

浏览器会在推测预渲染阶段就把目标页面的 DOM 构建好;当用户点击时,先截图当前页面、激活隐藏 tab、匹配 view-transition-name、播放形变动画,整套动作在一个 vsync 帧内完成。用户看到的是"图片从卡片位置飞到详情页头图位置"的丝滑过渡,而不是白屏闪烁。这是 MPA 反攻 SPA 阵地的关键组合拳,也让 INP 主线程优化之外多了一条降低感知延迟的路径。

如何用 Chrome DevTools 调试推测加载?

预渲染发生在隐藏的独立渲染进程中,常规 DevTools 面板无法直接查看。Chrome 提供了专门的调试入口:

  1. 打开目标页面,按 F12 或 Cmd+Option+I 打开 DevTools。
  2. 切换到 Application 面板,左侧 Background services 下点击 Speculative loads
  3. 顶部有三个子标签:This page 显示当前页触发的规则;Speculations 列出每个候选 URL 及其状态(Ready/Running/Failure);Rules 展示解析后的 JSON 规则。
  4. 点击任意 URL 可查看失败原因,例如 MojoBinderPolicy(某个 API 在预渲染中被禁用)、MemoryLimitExceededInvalidSchemeRedirect(跨域重定向)等。

常见失败码速查:PrerenderCancelled_UAChange 表示动态修改了 User-Agent;PrerenderCancelled_LoginRequired 表示目标页返回 401;PrerenderCancelled_Audible 表示后台页面尝试播放声音。这些都是浏览器主动杀掉预渲染进程以保护用户体验的信号。参考 Chrome DevTools 官方调试文档可获得完整失败码列表与 case-by-case 修复建议。

Safari 与 Firefox 不支持怎么办?

截至 2026 年 7 月,Safari 26 与 Firefox 128 均不支持 Speculation Rules API,非 Chromium 浏览器会静默忽略 <script type="speculationrules"> 标签。这不是灾难,你的站点在这些浏览器上会 fallback 到"普通导航"的表现,只是拿不到速度红利。推荐的降级策略:

  • 基础层:为所有关键下一跳页面写传统 <link rel="prefetch" href="/checkout">,全平台兼容,覆盖到 Safari/Firefox 用户。
  • 增强层:Chromium 浏览器额外加载 Speculation Rules,享受 prerender 级别的速度。
  • PWA 层:在 Service Worker 里用 caches.addAll(['/checkout', '/product/...']) 提前把 HTML 灌进 Cache Storage,等同于跨浏览器的"手动 prefetch"。

数据佐证:一个典型电商站 Chromium 占比约 72%(Chrome 65% + Edge 5% + 三星浏览器 2%),把 72% 用户的 LCP 打到 300ms 已经能显著拉高整站的 Core Web Vitals 中位数。别忘了 Google 的 CrUX 数据是分位数指标,Chromium 用户的进步会直接体现在 p75 上。这也是为什么 Shopify、Ray-Ban、Cloudflare 都优先押注这项技术。

常见问题

Speculation Rules API 需要 HTTPS 吗?

是的。规范要求当前页面和目标页面都必须是安全上下文(HTTPS 或 localhost)。跨源预渲染额外要求目标响应包含 Supports-Loading-Mode: credentialed-prerender 响应头,否则会被浏览器拒绝激活。

预渲染会不会导致我的服务器被 CDN 回源压垮?

可能会。moderate 档同时最多 2 个 prerender,但一个页面可能有几十个链接,每次悬停都可能触发。生产环境建议:一是使用请求头 Sec-Purpose: prefetch;prerender 识别推测请求,在 CDN 层做限流或缓存打标;二是核心业务端点(下单、支付、登出)用 href_matches 显式排除。

Speculation Rules 与 Next.js/Nuxt 的路由预取冲突吗?

不冲突,但会重复工作。Next.js 15 已在 App Router 中原生集成 Speculation Rules(next/link 会自动注入规则),关闭其内置的 SPA 预取(prefetch=false)反而更省资源。Nuxt 4 需要手动通过 useHead 注入 <script type="speculationrules">

如何测量 Speculation Rules 带来的真实性能提升?

使用 web-vitals 库上报 navigation.activationStart。预渲染激活的页面这个值会大于 0,其它字段(LCP、FCP、TTFB)都相对 activationStart 计算,因此可以对比"命中"与"未命中"两组会话的 CWV 差异。在 Chrome 用户体验报告(CrUX)中,2026 年 3 月起 navigation_types 维度已新增 prerenderprefetch 两个分类。

用户在浏览器里禁用了预加载还会生效吗?

不会。Chrome 的"预加载页面"设置(chrome://settings/performance)关闭、系统进入省流量模式、设备低电量或 CPU 负载过高时,浏览器会自动放弃所有推测加载。这也是 Speculation Rules 相对安全的一层保护,最坏情况就是不生效,不会伤害用户体验。

文章更新记录 (1)
  • — SEO meta refreshed (title and description updated)
Editorial Team
关于作者 Editorial Team

Our team of expert writers and editors.