对 Speculation Rules API 的改进

Chrome 团队一直致力于对 Speculation Rules 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 源规则,它有四种设置,Chrome 具有以下启发法:

  • immediate:用于尽快(即在观察到推测规则后)进行推测。
  • eager:目前的行为与 immediate 设置相同,但未来我们会考虑将其放置在 immediatemoderate 之间的某个位置。
  • moderate:如果将鼠标指针悬停在链接上 200 毫秒(或 pointerdown 事件,如果时间较短,并且在移动设备上没有 hover 事件,则会发生推测)。
  • conservative:用于推测指针或触摸事件。

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

document 规则的默认 eagernessconservative。由于一个文档可以包含多个网址,因此应谨慎使用 immediateeager 作为 document 规则(另请参阅下面的 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 还将防止在特定情况下使用推测,包括:

  • 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 紧急程度设置的文档规则:

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

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

将鼠标悬停在水果上时,您会看到页面正在预渲染。点击这些配方可显示比其中一个非预渲染的配方要快得多的 LCP 时间。以下视频中也对此演示了说明:

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

对推测规则的平台支持

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

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

WordPress

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

有两组可用的设置:推测模式即时性设置:

包含“推测规则”设置的 WordPress 设置“阅读”面板的屏幕截图。共有两个选项:“推测模式”(提供预提取或预渲染选项)和“紧急程度”设置(具有“保守”“中等”或“紧急”设置)。
WordPress Speculation Rules 插件

对于更复杂的设置(例如,要从预提取或预呈现某些网址),请参阅相关文档

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 Down 制作的缩略图,来自 Unsplash 网站