对 Speculation Rules API 的改进

Chrome 团队一直在努力对 Speculation Rules API 进行一些令人兴奋的更新,该 API 可通过预加载甚至预渲染未来的导航来提升导航性能。这些额外改进现已在 Chrome 122 中推出(部分功能在较低版本中也可用)。

这些更改大大简化了预提取和预渲染网页的部署,并减少了浪费,我们希望这能鼓励更多用户采用。

其他功能

首先,我们将介绍 Speculation Rules API 中新增的内容以及如何使用这些内容。之后,我们会向您展示一个演示,让您了解这些功能的实际运作方式。

文档规则

以前,Speculation Rules API 的运作方式是指定要预提取或预渲染的网址列表:

<script type="speculationrules">
{
  "prerender": [
    {
      "source": "list",
      "urls": ["next.html", "next2.html"]
    }
  ]
}
</script>

推测规则是半动态的,因为可以添加新的推测规则脚本,并移除旧脚本以舍弃这些推测(请注意,更新现有推测规则脚本的 urls 列表不会触发推测的更改)。不过,它仍然将网址的选择权交给了网站,网站可以通过在网页请求时从服务器发送网址,也可以通过客户端 JavaScript 动态创建此列表。

列表规则仍然适用于更简单的用例(下一个导航选项来自一小组明显的选项),或更高级的用例(网址列表是根据网站所有者想要使用的任何启发词语动态计算的,然后插入到网页中)。

作为替代方案,我们很高兴地推出了使用文档规则自动查找链接的新选项。其工作原理是根据 where 条件从文档本身获取网址。这可以基于链接本身:

<script type="speculationrules">
{
  "prerender": [{
    "source": "document",
    "where": {
      "and": [
        { "href_matches": "/*" },
        { "not": {"href_matches": "/logout/*"}}
      ]
    },
    "eagerness": "moderate"
  }]
}
</script>

CSS 选择器也可以作为 href 匹配的替代方案,或与 href 匹配结合使用,以查找当前网页中的链接:

<script type="speculationrules">
{
  "prerender": [{
    "source": "document",
    "where": {
      "and": [
        { "selector_matches": ".prerender" },
        { "not": {"selector_matches": ".do-not-prerender"}}
      ]
    },
    "eagerness": "moderate"
  }]
}
</script>

这样一来,您就可以在整个网站中使用单个推测规则集,而不是为每个网页设置特定的推测规则集,从而大大简化了网站部署推测规则的流程。

当然,预渲染网页上的所有链接肯定会浪费资源,因此我们在推出这项新功能时,还引入了 eagerness 设置。

热切

对于任何类型的推测,精确率和召回率与提前时间之间存在权衡。在网页加载时预渲染所有链接意味着您几乎肯定会预渲染用户点击的链接(假设他们点击的是网页上的同站链接),并且会尽可能提前预渲染,但可能会极大地浪费带宽。

另一方面,仅在用户点击链接后预渲染可以避免浪费,但代价是缩短准备时间。这意味着,在浏览器切换到该网页之前,它不太可能完成预渲染。

借助 eagerness 设置,您可以定义应何时运行推测,将何时推测与要对哪些网址执行推测分开。eagerness 设置适用于 listdocument 来源规则,具有四种设置,Chrome 对此有以下启发词语:

  • immediate:该设置用于尽快进行推测,即观察到推测规则后立即进行推测。
  • eager:该设置的行为目前与 immediate 设置相同,但以后,我们会将其定位为介于 immediatemoderate 之间的设置。
  • moderate:当您将光标悬停在链接上达到 200 毫秒时(或者发生 pointerdown 事件时,以更快者为准;在移动设备上没有 hover 事件),该设置会执行推测。
  • conservative:在发生指针点击或轻触时,该设置会执行推测。

list 规则的默认 eagernessimmediatemoderateconservative 选项可用于将 list 规则限制为仅适用于用户与特定列表中的网址互动的情况。不过,在许多情况下,包含适当 where 条件的 document 规则可能更合适。

document 规则的默认 eagernessconservative。鉴于文档可以包含多个网址,因此在为 document 规则使用 immediateeager 时应谨慎(另请参阅下文中的 Chrome 限制部分)。

要使用哪个 eagerness 设置取决于您的网站。对于非常简单的静态网站,更积极地进行推测可能成本很低,并且对用户有益。架构更复杂且网页载荷更重的网站可能更倾向于通过减少推测次数来减少浪费,直到您从用户那里获得更多积极的意图信号来限制浪费。

moderate 选项是一个折衷方案,许多网站都可以从以下简单的推测规则中受益,该规则会在用户悬停或按下指针时预渲染所有链接,是一种基本但强大的推测规则实现:

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

Chrome 限制

即使选择了 eagerness,Chrome 也设置了限制,以防止过度使用此 API:

eagerness 预取 预渲染
immediate/eager 50 10
moderate/conservative 2 (FIFO) 2 (FIFO)
Chrome 中的推测限制

moderateconservative 设置(取决于用户互动)以先进先出 (FIFO) 方式运行。达到上限后,新推测将导致最早的推测被取消并替换为较新的推测,以节省内存。

由于 moderateconservative 推测是由用户触发的,因此我们可以使用较低的阈值(2)来节省内存。immediateeager 设置不是由用户操作触发的,因此限制更高,因为浏览器无法知道需要哪些设置以及何时需要这些设置。

被推出 FIFO 队列而取消的推测可以再次触发(例如,再次将鼠标悬停在该链接上),这将导致系统重新推测该网址。在这种情况下,之前的推测可能会导致浏览器在该网址的 HTTP 缓存中缓存一些资源,因此重复推测应该会大大减少网络开销和时间开销。

immediateeager 限制也是动态的。使用这些推测级别移除推测规则脚本元素将通过取消这些已移除的推测来释放容量。如果这些网址包含在新网址脚本中且尚未达到上限,也可以重新指定。

Chrome 还会阻止在某些情况下使用推测,包括:

  • 省流模式
  • 节能模式
  • 内存限制。
  • “预加载网页”设置处于关闭状态(也由 uBlock Origin 等 Chrome 扩展程序明确关闭)。
  • 在后台标签页中打开的网页。

所有这些条件旨在减少过度推理对用户造成的不利影响。

可选 source

Chrome 122 将 source 键设为可选,因为可以根据 urlwhere 键的存在情况推断出该键。因此,以下两个推测规则是相同的:

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

Speculation-Rules HTTP 标头

您还可以使用 Speculation-Rules HTTP 标头传送推测规则,而不是直接将其包含在文档的 HTML 中。这样,CDN 便可以更轻松地进行部署,而无需更改文档内容本身。

Speculation-Rules HTTP 标头随文档一起返回,并指向包含推测规则的 JSON 文件的位置:

Speculation-Rules: "/speculationrules.json"

此资源必须使用正确的 MIME 类型,如果它是跨源资源,则必须通过 CORS 检查。

Content-Type: application/speculationrules+json
Access-Control-Allow-Origin: *

如果您想使用相对网址,则可能需要在推测规则中添加 "relative_to": "document" 键。否则,相对网址将相对于推测规则 JSON 文件的网址。如果您需要选择部分或全部同源链接,此功能可能特别有用。

更好地重复使用缓存

我们对 Chrome 中的缓存进行了多项改进,以便预提取(甚至预渲染)文档会在 HTTP 缓存中存储和重复使用资源。这意味着,即使未使用推测,推测仍可能带来未来好处。

这还会显著降低重新推理(例如,对于具有 moderate 急切设置的文档规则)的开销,因为 Chrome 会对可缓存资源使用 HTTP 缓存。

我们还支持新的 No-Vary-Search 提案,以进一步提高缓存重用率。

No-Vary-Search 支持

预提取或预渲染网页时,某些网址参数(在技术上称为搜索参数)可能对服务器实际传送的网页不重要,并且仅供客户端 JavaScript 使用。

例如,Google Analytics 使用 UTM 参数来衡量广告系列,但通常不会导致从服务器传送不同的网页。这意味着 page1.html?utm_content=123page1.html?utm_content=456 将从服务器传送相同的网页,因此可以从缓存中重复使用相同的网页。

同样,应用可以使用仅在客户端处理的其他网址参数。

No-Vary-Search 提案允许服务器指定不会导致传送的资源出现差异的参数,从而允许浏览器重复使用之前缓存的文档版本,这些版本仅因这些参数而有所不同。注意:目前,Chrome(以及基于 Chromium 的浏览器)仅支持将此属性用于预提取导航推测。

推测规则支持使用 expects_no_vary_search 指明预计返回 No-Vary-Search HTTP 标头的位置。这样做有助于进一步避免不必要的下载。

<script type="speculationrules">
{
  "prefetch": [{
    "urls": ["/products*"],
    "expects_no_vary_search": "params=(\"id\")"
  }]
}
</script>

<a href="/products?id=123">Product 123</a>
<a href="/products?id=124">Product 124</a>

在此示例中,商品 ID 为 123124/products 初始页 HTML 相同。不过,网页内容最终会因客户端呈现而有所不同,因为客户端呈现会使用 JavaScript 通过 id 搜索参数提取商品数据。因此,我们会提前预加载该网址,并且该网址应返回一个 No-Vary-Search HTTP 标头,表明该网页可用于任何 id 搜索参数。

不过,如果用户在预加载完成之前点击了任何链接,浏览器可能尚未收到 /products 页面。在这种情况下,浏览器不知道它是否会包含 No-Vary-Search HTTP 标头。然后,浏览器可以选择是否重新提取链接,或者等待预提取完成,以查看它是否包含 No-Vary-Search HTTP 标头。通过 expects_no_vary_search 设置,浏览器可以知道页面响应应包含 No-Vary-Search HTTP 标头,并等待该预提取完成。

演示

我们在 https://speculative-rules.glitch.me/common-fruits.html 上创建了一个演示,您可以使用该演示来查看采用 moderate 推断设置的文档规则的运作方式:

在 Glitch 中创建的演示网站的屏幕截图,其中列出了一些标有水果名称的链接。开发者工具已打开,并显示其中两个链接(apple.html 和 orange.html)已成功预渲染。
推测规则演示

打开 DevTools,点击 Application 面板。然后,在后台服务部分中,依次点击推测性加载推测窗格,并按状态列对数据进行排序。

当您将光标悬停在水果上时,您会看到页面预渲染。点击这些食谱后,您会发现其 LCP 时间比未预渲染的食谱要短得多。以下视频中也对此演示进行了说明:

您还可以参阅之前的“调试推测规则”博文,详细了解如何使用 DevTools 调试推测规则。

对推测规则的平台支持

虽然通过将推测规则注入 <script type="speculationrules"> 元素来实现推测规则相对简单,但借助平台支持,您只需点击一下即可完成此操作。我们一直在与各种平台和合作伙伴合作,以便更轻松地推出投机规则。

我们还在努力通过 Web Incubator Community Group (WICG) 规范该 API,以便其他浏览器也可以根据需要实现这项令人兴奋的 API。

WordPress

WordPress Core 性能团队(包括 Google 的开发者)创建了“推测规则”插件。借助此插件,您可以轻松地一键为任何 WordPress 网站添加文档规则支持。您还可以通过 WordPress Performance Lab 插件安装此插件,您也应考虑安装该插件,以便及时了解该团队提供的相关性能插件。

有两组设置可用:推测模式积极性设置:

显示“推测规则”设置的 WordPress“阅读”设置面板的屏幕截图。有两个选项:可选择预提取或预渲染的推测模式,以及可选择“保守”“中等”或“积极”的积极性设置。
WordPress 推测规则插件

对于更复杂的设置(例如,要排除某些网址以免预提取或预渲染),请参阅文档

Akamai

Akamai 是全球领先的 CDN 提供商之一,他们已经在积极尝试使用 Speculation Rules API 一段时间了。Akamai 已发布文档,介绍了客户如何在其 CDN 设置中启用此 API。他们之前还分享了此新 API 可带来的出色成效

NitroPack

NitroPack 是一款性能优化解决方案,它使用自定义导航 AI 来预测要添加到推测规则中的页面,旨在提供比将鼠标悬停在链接上更长的预留时间,同时避免对观察到的所有链接进行不必要的推测。如需了解详情,请参阅 Nitropack Speculation Rules API 文档。这项创新解决方案表明,旧版列表规则在与网站专用数据洞见搭配使用时,仍能发挥出强大作用。

Chrome 团队还与 NitroPack 合作举办了有关 Speculation Rules API 的在线讲座,为希望了解更多信息的用户提供了便利,包括深入探讨了在早期和频繁进行推测与在晚期和不太频繁进行推测之间需要考虑的事项。

Astro

Astro 在 4.2 中实验性地添加了使用 Speculation Rules API 预渲染网页的功能,使用 Astro 的开发者可以轻松启用此功能,同时对于不支持 Speculation Rules API 的浏览器,则会回退到标准预提取。如需了解详情,请参阅他们的客户端预渲染文档

总结

Speculation Rules API 中新增的这些功能让您可以更轻松地为网站使用这项令人兴奋的新性能功能,并且不太容易因未使用的推测而浪费资源。很高兴看到各平台已经开始采用此 API。我们希望在 2024 年看到更多开发者采用此 API,最终为最终用户提供更好的性能。

除了 Speculation Rules API 带来的性能提升之外,我们还非常期待看到它能带来哪些新的机会。View 转场效果是一项新 API,可让开发者更轻松地指定导航之间的转场效果。此功能目前适用于单页应用 (SPA),但多页版正在开发中(在 Chrome 中通过标志启用)。预渲染是该功能的自然补充,可确保没有延迟,否则会阻止过渡提供预期的用户体验改进。我们已经看到一些网站在尝试这种组合

我们期待在 2024 年进一步采用 Speculation Rules API,并会及时告知您我们对该 API 做出的任何进一步改进。

致谢

缩略图:Unsplash 上的 Robbie Down