对 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 匹配,以在当前网页中查找链接:

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

这样便可在整个网站中使用单个推测规则集,而不必为每个网页设置特定的规则集,从而大大简化了网站部署推测规则的操作。

当然,预渲染网页上的所有链接肯定会造成浪费,因此,借助这项新功能,我们引入了 eagerness 设置。

迫切

无论哪种推测,您都需要在精确率和召回率与交货期之间进行权衡取舍。在网页加载时预呈现所有链接,意味着您几乎肯定会预渲染用户点击的链接(假设他们点击的是同一网页上的同一链接),并会留出尽可能多的准备时间,但这样可能会浪费带宽。

另一方面,仅在用户点击链接后才进行预渲染可以避免浪费,但代价是大大缩短了准备时间。也就是说,在浏览器切换至该网页之前,系统不太可能完成预渲染。

借助 eagerness 设置,您可以定义应在何时运行推测,从而将推测出对哪些网址执行推测的时间eagerness 设置同时适用于 listdocument 来源规则,并且有 4 项设置。对于这些设置,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(先进先出) 2(先进先出)
Chrome 中的推测限制

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

moderateconservative 推测是由用户触发的这一事实,这使得我们可以使用更适中的阈值 2 来节省内存。immediateeager 设置不是由用户操作触发的,因此具有较高的限制,因为浏览器无法知道哪些功能需要以及何时需要。

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

immediateeager 限制也是动态的。删除使用这些紧急程度级别的推测规则脚本元素将通过取消这些删除的推测来创建容量。如果这些网址包含在新的网址脚本中并且尚未达到限制,那么也可以重新推测它们。

Chrome 还会防止 Google 在特定情况下使用推测结果,这些情况包括:

  • Save-Data(保存数据)。
  • 节能模式
  • 内存限制。
  • 当系统显示“预加载网页”设置处于关闭状态(亦会被 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 紧急设置的文档规则的实际运用:

<ph type="x-smartling-placeholder">
</ph> 一个演示网站的屏幕截图,该网站在小故障信息中列出了多个标有“水果”的链接。开发者工具已打开,显示有两个链接(apple.html 和 orange.html)已成功预渲染。
推测规则演示

打开开发者工具,点击 Application 面板。然后,在后台服务部分中,依次点击推测加载推测窗格,并按状态列进行排序。

将鼠标悬停在水果上时,您会看到网页正在预渲染。点击某个食谱的 LCP 时间会比某个非预渲染的食谱快得多。以下视频也对此演示进行了说明:

您还可以查看之前的调试推测规则博文,详细了解如何使用开发者工具调试推测规则。

针对推测规则的平台支持

虽然通过将规则注入 <script type="speculationrules"> 元素来实现推测规则相对简单,但平台支持可以让一键操作变得简单。我们一直在与各种平台和合作伙伴合作,以便更轻松地推行推测规则。

此外,我们还在努力通过 Web Incubator 社区群组 (WICG) 实现 API 标准化,以便允许其他浏览器根据需要实现这个令人兴奋的 API。

WordPress

WordPress 核心效果团队(包括来自 Google 的开发者)创建了一个推测规则插件。借助此插件,只需点击一下即可将文档规则支持添加到任何 WordPress 网站。您也可以通过 WordPress Performance Lab 插件安装此插件。另外,建议您安装该插件,因为它会及时提供由团队提供的相关性能插件。

有两组设置可用:“推测模式”和“紧急程度”设置:

<ph type="x-smartling-placeholder">
</ph> 显示“推测规则”设置的 WordPress 设置阅读面板的屏幕截图。有两个选项:“推测模式”(包含预提取或预渲染选项)以及“紧急程度”设置(包含“保守”、“中等”或“即刻”设置)。
WordPress 推测规则插件

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

Akamai

Akamai 是全球领先的 CDN 提供商之一,他们现在一直在积极地试用 Speculation Rules API。Akamai 已发布有关客户如何在 CDN 设置中启用此 API 的文档。他们之前还分享了这一全新 API 可能带来的出色成效

NitroPack

NitroPack 是一种性能优化解决方案,会使用其自定义 Navigation 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。我们希望该 API 在 2024 年得到更广泛的采用,并最终为最终用户提供更好的性能。

除了 Speculation Rules API 性能上的提升之外,我们也很高兴地看到它带来了哪些新机会。视图过渡是一个新 API,可让开发者更轻松地指定导航之间的过渡。此功能目前适用于单页应用 (SPA),但还在开发多页版本(在 Chrome 中带有标志)。预渲染是该功能的自然附加项,可确保不会出现延迟,否则,过渡效果会妨碍用户体验的改善。我们已经看到有网站对此组合进行了实验

我们期待在 2024 年进一步采用 Speculation Rules API,一旦该 API 有任何进一步改进,我们会及时通知您。

致谢

Robbie DownUn 创立视频中制作的缩略图