在 Chrome 中预渲染网页以实现即时网页导航

浏览器支持

  • Chrome:109。 <ph type="x-smartling-placeholder">
  • Edge:109。 <ph type="x-smartling-placeholder">
  • Firefox:不支持。 <ph type="x-smartling-placeholder">
  • Safari:不支持。 <ph type="x-smartling-placeholder">

Chrome 团队恢复了对用户未来可能会访问的网页的完整预渲染功能。

预渲染简史

过去,Chrome 支持 <link rel="prerender" href="/next-page"> 资源提示,但除 Chrome 之外,它并未得到广泛支持,而且该 API 的表现力不是很好。

这种使用链接 rel=prerender 提示的旧版预渲染已被弃用,取而代之的是 NoState Prefetch,后者会提取未来网页所需的资源,但不会完全预渲染网页,也不会执行 JavaScript。NoState 预提取确实可以通过改善资源加载来提高网页性能,但无法像完整预渲染那样提供即时网页加载。

Chrome 团队现已将完全预渲染功能重新引入 Chrome 中。为避免现有使用方式的复杂化以及未来预渲染的未来扩展,这种新的预渲染机制将不会使用 <link rel="prerender"...> 语法,该语法在 NoState 预提取中仍存在,并计划在未来某个时间点弃用此语法。

网页是如何预渲染的?

网页可以通过以下四种方式之一进行预渲染,这些方式都旨在加快导航速度:

  1. 当您在 Chrome 的地址栏(也称为“多功能框”)中输入网址时,Chrome 可能会根据您的之前的浏览记录,自动为您预呈现相应网页(如果它很有把握会让您访问该网页)。
  2. 当您使用书签栏时,只需将鼠标指针悬停在某个书签按钮上,Chrome 就会自动预呈现网页。
  3. 当您在 Chrome 地址栏中输入搜索字词时,Chrome 可能会根据搜索引擎的指示自动预呈现搜索结果页。
  4. 网站可以使用 Speculation Rules API,以编程方式告知 Chrome 要预呈现哪些网页。这会取代 <link rel="prerender"...> 之前的运作方式,并允许网站根据网页的推测规则主动预呈现网页。这些代码可以静态存在于网页上,也可以由 JavaScript 根据网页所有者的喜好动态注入。

在每种情况下,预渲染的行为就像网页在不可见的背景标签页中打开并“激活”一样将前景标签页替换为该预渲染页面如果网页在完全预渲染之前激活,则其当前状态为“前台”并继续加载,这意味着您仍然能抢占先机。

由于预渲染的网页在打开时处于隐藏状态,因此一些导致侵扰性行为的 API(例如提示)不会在此状态下激活,而是会延迟到网页激活后才能启用。在极少数情况下,如果还无法做到这一点,系统会取消预渲染。Chrome 团队正致力于以 API 的形式公开预渲染取消原因,并增强开发者工具的功能,以便更轻松地识别此类极端情况。

预渲染的影响

预渲染可近乎即时地加载网页,如以下视频所示:

<ph type="x-smartling-placeholder">
</ph>
预渲染的影响示例。

示例网站已经是一个加载速度很快的网站,但即便如此,您也可以看出预呈现如何改善用户体验。因此,这也会对网站的核心网页指标产生直接影响,包括 LCP 接近于零、CLS 降低(因为所有加载 CLS 都发生在初始查看之前)和改善的 INP(因为加载应在用户进行互动之前完成)。

即使网页在完全加载之前激活,让网页加载时间较快也有助于提升加载体验。如果在预渲染仍在进行期间激活了某个链接,预渲染页面会移至主框架并继续加载。

不过,预渲染会占用额外的内存和网络带宽。请注意不要过度预渲染,否则会浪费用户资源。仅在页面极有可能被导航到时预渲染。

如需详细了解如何在数据分析中衡量对性能的实际影响,请参阅衡量效果部分。

查看 Chrome 地址栏联想查询

对于第一个用例,您可以在 chrome://predictors 页面中查看 Chrome 对网址的联想查询:

<ph type="x-smartling-placeholder">
</ph> “Chrome 预测程序”页面已过滤,根据输入的文字显示低(灰色)、中(琥珀色)和高(绿色)的联想查询。
“Chrome Predictor”页面。

绿线表示置信度足以触发预渲染。在本示例中,输入“s”会给出合理的置信度(琥珀色),但如果您输入“sh”,那么 Chrome 就会有足够的信心,让您几乎每次都会导航到 https://sheets.google.com

此屏幕截图是在相对较新的 Chrome 安装中截取的,并且过滤掉了零置信度预测结果,但如果您查看自己的预测器,则可能会看到更多条目,甚至可能看到更多字符,才能达到足够高的置信度。

您可能会注意到,以下预测器也会触发地址栏的建议选项:

<ph type="x-smartling-placeholder">
</ph> Chrome 地址栏“提前输入”功能
地址栏“提前输入”功能。

Chrome 会根据您的输入和选择持续更新预测器。

  • 如果置信度超过 50%(显示为琥珀色),Chrome 会主动预连接到网域,但不会预呈现网页。
  • 如果置信度超过 80%(显示为绿色),Chrome 将会预呈现网址。

推测规则 API

对于 Speculation Rules API 预渲染选项,网络开发者可以在自己的网页上插入 JSON 指令,以告知浏览器要预渲染的网址:

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

或者通过文档规则(适用于 Chrome 121)执行,这些规则会根据 href 选择器(基于 网址 Pattern API)或 CSS 选择器预呈现在文档中找到的链接:

<script type="speculationrules">
{
  "prerender": [{
    "where": {
      "and": [
        { "href_matches": "/*" },
        { "not": {"href_matches": "/wp-admin"}},
        { "not": {"href_matches": "/*\\?*(^|&)add-to-cart=*"}},
        { "not": {"selector_matches": ".do-not-prerender"}},
        { "not": {"selector_matches": "[rel~=nofollow]"}}
      ]
    }
  }]
}
</script>

Chrome 团队准备了推测规则 Codelab,用于指导您向网站添加推测规则。

迫切

浏览器支持

  • Chrome:121。 <ph type="x-smartling-placeholder">
  • 边缘:121。 <ph type="x-smartling-placeholder">
  • Firefox:不支持。 <ph type="x-smartling-placeholder">
  • Safari:不支持。 <ph type="x-smartling-placeholder">

eagerness 设置用于指示应在何时触发推测,这对文档规则特别有用:

  • immediate:此选项用于尽快推测,即在遵守推测规则后立即进行推测。
  • eager:其行为与 immediate 设置完全相同,但将来,我们希望将其放置在 immediatemoderate 之间。
  • moderate:如果将指针悬停在某个链接上 200 毫秒(如果指针悬停在链接上的时间较短,那么它会执行推测;如果是在移动设备上没有 hover 事件,则按住 pointerdown 事件)。
  • conservative:此类型基于指针或轻触操作推测。

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

document 规则的默认 eagernessconservative。由于文档可以由许多网址组成,因此应谨慎针对 document 规则使用 immediateeager(另请参阅下文的 Chrome 限制部分)。

使用哪种 eagerness 设置取决于您的网站。对于轻量级的静态网站,进行更频繁的推测可能几乎没有成本,并且对用户有益。如果网站的架构更复杂、页面载荷更重,可能会更倾向于减少推测,直至从用户那里获得更积极的意图信号来减少浪费,从而减少浪费。

moderate 选项处于中等位置,以下推测规则会预呈现链接,即在将指针悬停在链接上达 200 毫秒时或者在指针按下事件发生时预呈现链接,这是作为推测规则的基本(但功能强大)的实现方法,许多网站可以从中获益:

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

预取

推测规则也可用于仅预提取网页而不进行完整预渲染。这通常是一个很好的预渲染第一步:

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

Chrome 限制

Chrome 设有限制,以防止过度使用 Speculation Rules API:

渴望 预取 预渲染
immediate/eager 50 10
moderate/conservative 2(先进先出) 2(先进先出)
Chrome 中的推测限制

moderateconservative 设置(取决于用户互动)以先进先出 (FIFO) 方式运作:达到上限后,新的推测会导致取消最早的推测,并将其替换为较新的推测,从而节省内存。已取消的推测可能会再次触发(例如,再次将鼠标悬停在该链接上),这将使系统重新推测该网址,从而排除最早的推测。在这种情况下,之前的推测会在 HTTP 缓存中为该网址缓存所有可缓存资源,因此推测更长的时间应该可以降低成本。因此,该限值被设为适中的阈值 2。静态列表规则不是由用户操作触发的,因此具有较高的限制,因为浏览器无法知道需要哪些规则以及何时需要这些规则。

immediateeager 限制也是动态的,因此移除 list 网址脚本元素将通过取消这些已移除的推测来创建容量。

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

  • Save-Data(保存数据)。
  • 节能模式(当已启用且电量不足时)。
  • 内存限制。
  • 当系统显示“预加载网页”设置处于关闭状态(亦会被 uBlock Origin 等 Chrome 扩展程序明确关闭)。
  • 在后台标签页中打开的网页。

在启用跨源 iframe 之前,Chrome 也不会在预渲染的网页上呈现跨源 iframe。

所有这些条件都是为了减少过度推测对用户有害时造成的影响。

如何在网页中添加推测规则

推测规则可以静态包含在网页的 HTML 中,也可以通过 JavaScript 动态插入网页:

  • 静态包含的推测规则:例如,新闻媒体网站或博客可能会预渲染最新文章(如果大多数用户下次导航时这些文章);或者,可以使用 moderateconservative 的文档规则在用户与链接互动时进行推测。
  • 动态插入的推测规则:可以基于应用逻辑、针对用户进行个性化设置,或基于其他启发法。

支持基于悬停或点击链接等操作进行动态插入的开发者(就像许多库过去使用 <link rel=prefetch> 所做的那样)建议查看文档规则,因为此类规则允许浏览器处理您的许多用例。

推测规则可在主框架的 <head><body> 中添加。系统不会对子框架中的推测规则执行操作,预渲染网页中的推测规则仅在网页激活后才会对其执行操作。

Speculation-Rules HTTP 标头

浏览器支持

  • Chrome:121。 <ph type="x-smartling-placeholder">
  • 边缘:121。 <ph type="x-smartling-placeholder">
  • Firefox:不支持。 <ph type="x-smartling-placeholder">
  • Safari:不支持。 <ph type="x-smartling-placeholder">

来源

您也可以使用 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 文件的网址。如果您需要选择部分或所有同源链接,这可能会特别有用。

推测规则和 SPA

推测规则仅适用于由浏览器管理的完整页面导航,而不适用于单页应用 (SPA) 或 App Shell 页面。这些架构不使用文档提取,而是通过 API 或部分提取数据或页面,然后对这些数据或页面进行处理并呈现在当前页面中。这些系统所谓的“软导航”所需的数据可在推测规则之外由应用预提取,但无法预渲染。

推测规则可用于从前一页面预渲染应用本身。这有助于抵消一些 SPA 造成的额外初始加载费用。不过,应用内的路线更改无法预渲染。

调试推测规则

如需了解有助于查看和调试这个新 API 的 Chrome 开发者工具新功能,请参阅专门介绍调试推测规则的帖子

多项推测规则

您还可以将多条推测规则添加到同一网页,并将这些规则附加到现有规则。因此,以下不同方式都会导致 one.htmltwo.html 预渲染:

网址列表

<script type="speculationrules">
{
  "prerender": [
    {
      "urls": ["one.html", "two.html"]
    }
  ]
}
</script>

多个 speculationrules 脚本

<script type="speculationrules">
{
  "prerender": [
    {
      "urls": ["one.html"]
    }
  ]
}
</script>
<script type="speculationrules">
{
  "prerender": [
    {
      "urls": ["two.html"]
    }
  ]
}
</script>

一组 speculationrules 中的多个列表

<script type="speculationrules">
{
  "prerender": [
    {
      "urls": ["one.html"]
    },
    {
      "urls": ["two.html"]
    }
  ]
}
</script>

浏览器支持

  • Chrome:121。 <ph type="x-smartling-placeholder">
  • 边缘:121。 <ph type="x-smartling-placeholder">
  • Firefox:不支持。 <ph type="x-smartling-placeholder">
  • Safari:不支持。 <ph type="x-smartling-placeholder">

来源

预提取或预呈现网页时,某些网址参数(技术上称为“搜索参数”)可能对服务器实际传送的网页并不重要,而只由客户端 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://a.example.com 可能会在 https://b.example.com 上预渲染网页)。要使用这项功能,推测的网页(在本例中为 https://b.example.com)需要通过添加 Supports-Loading-Mode: credentialed-prerender HTTP 标头来选择启用,否则 Chrome 将取消推测结果。

未来的版本还可能允许对非同一网站的跨源网页进行预渲染,前提是预渲染的网页不存在 Cookie,并且预渲染的网页选择启用类似的 Supports-Loading-Mode: uncredentialed-prerender HTTP 标头。

推测规则已经支持跨源预提取,但同样只在跨源网域的 Cookie 不存在时提供支持。如果用户之前曾访问过该网站,且存在 Cookie,则系统不会触发推测,并在开发者工具中显示失败。

考虑到目前存在的这些局限性,有一种可能尽可能改善内部链接和外部链接的用户体验的模式是预渲染同源网址并尝试预提取跨源网址:

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

为了确保安全,必须设置限制,防止对跨源链接进行跨源推测。对于跨源目的地而言,这是与 <link rel="prefetch"> 相比的改进,因为跨源目标同样不会发送 Cookie,但仍会尝试预提取,这会导致需要重新发送的预提取浪费,或者更糟糕的是,页面加载不正确。

对于由 Service Worker 控制的页面进行预提取,不支持使用推测规则。我们正在努力添加这项支持。请关注此 Support Service Worker 问题,了解最新动态。由 Service Worker 控制的网页支持预渲染。

检测推测规则 API 支持

您可以通过标准 HTML 检查来检测 Speculation Rules API 支持:

if (HTMLScriptElement.supports && HTMLScriptElement.supports('speculationrules')) {
  console.log('Your browser supports the Speculation Rules API.');
}

通过 JavaScript 动态添加推测规则

以下是使用 JavaScript 添加 prerender 推测规则的示例:

if (HTMLScriptElement.supports &&
    HTMLScriptElement.supports('speculationrules')) {
  const specScript = document.createElement('script');
  specScript.type = 'speculationrules';
  specRules = {
    prerender: [
      {
        urls: ['/next.html'],
      },
    ],
  };
  specScript.textContent = JSON.stringify(specRules);
  console.log('added speculation rules to: next.html');
  document.body.append(specScript);
}

您可以在此预渲染演示页面上观看使用 JavaScript 插入功能的 Speculation Rules API 预渲染演示。

出于安全考虑,使用 innerHTML 直接将 <script type = "speculationrules"> 元素插入 DOM 不会注册推测规则,您必须如前所述添加这些规则。不过,使用 innerHTML 动态插入的包含新链接的内容将按照网页上的现有规则选取。

同样,如果直接修改 Chrome DevTools 中的 Elements 面板来添加 <script type = "speculationrules"> 元素,则不会注册推测规则。为了插入规则,必须从控制台运行用于将此属性动态添加到 DOM 的脚本。

通过跟踪代码管理器添加推测规则

如需使用 Google 跟踪代码管理器 (GTM) 等跟踪代码管理器添加推测规则,必须通过 JavaScript 插入这些规则,而不是直接通过 GTM 添加 <script type = "speculationrules"> 元素,原因与上述原因相同:

<ph type="x-smartling-placeholder">
</ph> Google 跟踪代码管理器中的自定义 HTML 代码配置
通过 Google 跟踪代码管理器添加推测规则

请注意,此示例使用 var,因为 GTM 不支持 const

取消推测规则

移除推测规则会导致预渲染被取消,但届时,启动预渲染所需的资源很有可能已经消耗,因此建议不要在有可能需要取消预渲染的情况下不要进行预渲染。

推测规则和内容安全政策

由于推测规则使用 <script> 元素,尽管它们仅包含 JSON,因此如果网站使用哈希值或 Nonce,则需要包含在 script-src Content-Security-Policy中。

可以向 script-src 添加新的 inline-speculation-rules,从而支持从哈希脚本或 Nonce 脚本注入的 <script type="speculationrules"> 元素。这不支持初始 HTML 中包含的规则,因此需要通过 JavaScript 为使用严格 CSP 的网站注入规则。

检测并停用预渲染

预渲染通常会给用户带来良好的体验,因为预渲染可以快速呈现网页(通常是即时渲染)。这对用户和网站所有者都有好处,因为预渲染的网页能够提供更出色的用户体验,而其他方式可能很难实现。

不过,在某些情况下,您可能不希望系统预呈现网页,例如,网页状态因初始请求或网页上执行的 JavaScript 而改变时。

在 Chrome 中启用和停用预渲染

仅为启用了“预加载网页”的 Chrome 用户启用预渲染设置(位于 chrome://settings/performance/ 中)。此外,在低内存设备上或操作系统处于“节省流量”或“节能模式”模式时,系统也会停用预渲染。请参阅 Chrome 限制部分。

检测并停用预渲染服务器端

预渲染的网页将使用 Sec-Purpose HTTP 标头发送:

Sec-Purpose: prefetch;prerender

使用 Speculation Rules API 的预提取网页会将此标头设置为仅 prefetch

Sec-Purpose: prefetch

服务器可以根据此标头进行响应,以记录推测请求、返回不同的内容或阻止进行预渲染。如果返回了非成功响应代码(即不是 200 或 304),系统便不会预渲染网页,而会舍弃任何预提取网页。

如果您不希望预渲染特定网页,这是确保不会发生这种情况的最佳方法。不过,为了提供最佳体验,建议您改用 JavaScript 允许预渲染,但延迟执行仅在用户实际查看网页后才应执行的操作。

检测 JavaScript 中的预渲染

在网页预渲染时,document.prerendering API 将返回 true。网页可以使用此变量来阻止(或延迟)预渲染期间的特定活动,直到网页实际激活为止。

预渲染的文档激活后,PerformanceNavigationTimingactivationStart 也会设置为非零时间,表示从预渲染开始到文档实际激活之间的时间。

您可以使用函数来检查预渲染预渲染的网页,如下所示:

function pagePrerendered() {
  return (
    document.prerendering ||
    self.performance?.getEntriesByType?.('navigation')[0]?.activationStart > 0
  );
}

若要查看页面是否预渲染(全部或部分),最简单的方法是在页面激活后打开开发者工具,然后在控制台中输入 performance.getEntriesByType('navigation')[0].activationStart。如果返回非零值,则表示网页是预渲染的:

<ph type="x-smartling-placeholder">
</ph> Chrome 开发者工具中的控制台显示“activationStart”为正,表示网页是预渲染的
在控制台中测试预渲染。

当查看页面的用户激活该页面后,系统将在 document 上分派 prerenderingchange 事件,该事件随后可用于启用之前默认会在页面加载时启动,但您想延迟到用户实际查看页面后启动的 activity。

借助这些 API,前端 JavaScript 可以正确检测预渲染的页面并据此采取行动。

对分析的影响

Google Analytics 用于衡量网站使用情况,例如使用 Google Analytics 来衡量网页浏览和事件。或者使用真实用户监控 (RUM) 衡量网页的性能指标。

仅当用户极有可能加载网页时,才应预渲染网页。因此,Chrome 地址栏预呈现选项仅在极有可能发生(超过 80% 的情况下)时才会使用。

不过,尤其是在使用 Speculation Rules API 时,预渲染的网页可能会影响 Google Analytics,且网站所有者可能需要添加额外的代码,以便仅在启用时对预渲染的网页启用 Google Analytics,因为并非所有分析服务提供商都会默认执行此操作。

这可以通过使用 Promise 来实现,该方法会在文档正在预渲染时等待 prerenderingchange 事件,如果现在处于预渲染状态,则立即解析:

// Set up a promise for when the page is activated,
// which is needed for prerendered pages.
const whenActivated = new Promise((resolve) => {
  if (document.prerendering) {
    document.addEventListener('prerenderingchange', resolve, {once: true});
  } else {
    resolve();
  }
});

async function initAnalytics() {
  await whenActivated;
  // Initialise your analytics
}

initAnalytics();

另一种方法是延迟分析活动,直到网页首次显示为止,这既涵盖预渲染的情况,也涵盖在后台打开标签页的情况(例如,通过右键点击并在新标签页中打开):

// Set up a promise for when the page is first made visible
const whenFirstVisible = new Promise((resolve) => {
  if (document.hidden) {
    document.addEventListener('visibilitychange', resolve, {once: true});
  } else {
    resolve();
  }
});

async function initAnalytics() {
  await whenFirstVisible;
  // Initialise your analytics
}

initAnalytics();

虽然这对于分析和类似用例很有意义,但在某些情况下,您可能需要针对这些用例加载更多内容,因此可能需要使用 document.prerenderingprerenderingchange 来专门定位预渲染页面。

在预渲染期间隐藏其他内容

前面讨论的 API 也可用于在预渲染阶段保留其他内容。这可以是您不希望在预渲染阶段运行的 JavaScript 特定部分或整个脚本元素。

例如,假设存在以下脚本:

<script src="https://example.com/app/script.js" async></script>

您可以将此更改为动态插入的脚本元素,该元素仅根据之前的 whenActivated 函数插入:

async function addScript(scriptUrl) {
  await whenActivated;
  const script = document.createElement('script');
  script.src = 'scriptUrl';
  document.body.appendChild(script);
}

addScript('https://example.com/app/script.js');

这有助于阻止包含分析的不同脚本,或根据状态或其他在访问期间会发生变化的变量来呈现内容。例如,建议、登录状态或购物篮图标都可以隐藏起来,以确保呈现最新信息。

如果使用预渲染,这种情况更有可能发生,但对于在前面提到的后台标签页中加载的网页而言,上述情况同样适用(因此可以使用 whenFirstVisible 函数来代替 whenActivated)。

在许多情况下,理想情况下,还应针对常规的 visibilitychange 更改检查状态。例如,当返回到后台网页时,应使用购物篮中商品的最新数量来更新所有购物篮计数器。因此,这不是预渲染特有的问题,而预渲染只是让现有问题更加明显。

Chrome 缓解了对手动封装脚本或函数的部分需求的一种方式:如前所述,系统会阻止某些 API,并且第三方 iframe 也不会呈现,因此,除了这些内容之外,还需要手动阻止呈现第三方 iframe。

衡量性能

若要衡量性能指标,Google Analytics 应考虑根据激活时间(而不是浏览器 API 报告的网页加载时间)来衡量是否更好。

对于 Chrome 通过 Chrome 用户体验报告衡量的核心网页指标,这些指标旨在衡量用户体验。因此,这些指标是根据启用时间来衡量的。这通常会导致 LCP 为 0 秒,这表明这是改进核心网页指标的好方法。

从版本 3.1.0 开始,web-vitals已更新,现在处理预渲染导航的方式与 Chrome 衡量核心网页指标的方式相同。如果网页是完全或部分预渲染的,则此版本还会在 Metric.navigationType 属性中针对这些指标标记预渲染导航。

衡量预渲染

通过 PerformanceNavigationTiming 这个非零 activationStart 条目,可以看出网页是否为预渲染的网页。然后,在记录网页浏览量时,可以使用自定义维度或类似方法进行记录,例如使用前面介绍的 pagePrerendered 函数

// Set Custom Dimension for Prerender status
gtag('set', { 'dimension1': pagePrerendered() });
// Initialise GA - including sending page view by default
gtag('config', 'G-12345678-1');

这样一来,您的分析数据就可以显示与其他类型的导航相比,预渲染的导航数量,并且您可以将任何性能指标或业务指标与这些不同的导航类型关联起来。网页加载速度越快,用户满意度越高,这通常对业务指标产生切实的影响,具体如我们的案例研究所示。

在衡量为实现即时导航而预渲染网页对业务的影响时,您可以确定是否值得投入更多精力使用此技术来预渲染更多导航,或调查网页未预渲染的原因。

衡量命中率

除了衡量在预渲染后访问的网页的影响之外,衡量预渲染而随后未访问的网页也很重要。这可能意味着,您进行了过多的预渲染,浪费了用户的宝贵资源,而几乎没有什么好处。

为此,可以通过以下方式进行衡量:在插入推测规则时(使用 HTMLScriptElement.supports('speculationrules') 检查浏览器是否支持预渲染)时触发分析事件,以表明已请求预渲染。(请注意,如前所述,预渲染仅是请求了预渲染,并不表示预渲染已开始或已完成,因为预渲染只是对浏览器的提示,它可能会根据用户设置、当前内存用量或其他启发法选择不预渲染网页。)

然后,您可以将这些事件的数量与实际的预渲染网页浏览量进行比较。或者,您也可以在激活时触发另一个事件,这样更容易进行比较。

“成功命中率”然后观察这两个数字之间的差异就可以得出大致的答案。对于使用 Speculation Rules API 预渲染的网页,您可以适当调整规则,以确保保持较高的命中率,以便在用尽用户资源帮助他们与不必要地使用资源之间保持平衡。

请注意,有些预呈现的发生可能是由于地址栏预呈现所致,而不仅仅是由您的推测规则所致。如果您想进行区分,可以查看 document.referrer(对于地址栏导航(包括预渲染的地址栏导航)而言,此字段将为空白)。

此外,请务必查看没有进行预渲染的网页,因为这可能表示这些网页不符合预渲染的条件,即使通过地址栏也不行。这可能意味着,您无法从这项性能提升中获益。Chrome 团队正计划添加额外的工具来测试预渲染资格(可能类似于 bfcache 测试工具),还可能会添加一个 API 来揭示预渲染失败的原因。

对扩展程序的影响

请参阅 Chrome 扩展程序:扩展 API 以支持即时导航中的专用帖子,其中详细介绍了扩展程序作者可能需要考虑的关于预渲染页面的一些其他注意事项。

反馈

Chrome 团队正在积极开发预渲染功能,我们计划在 Chrome 108 版本中扩大可用功能的范围。我们欢迎您针对 GitHub 代码库或使用我们的问题跟踪器提供反馈,也期待收到和分享这个令人兴奋的新 API 的案例研究。

致谢

缩略图,作者:Marc-Olivier Jodoin,在 Un 节点上