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

浏览器支持

  • Chrome:109。
  • Edge:109。
  • Firefox:不受支持。
  • Safari:不受支持。

Chrome 团队已恢复对用户可能要浏览的未来网页进行完整预渲染。

预渲染简史

过去,Chrome 支持 <link rel="prerender" href="/next-page"> 资源提示,但除了 Chrome 之外,它没有广泛的支持,而且它并不是一个非常富有表现力的 API。

使用链接 rel=prerender 提示的这种旧版预渲染已废弃,取而代之的是 NoState 预提取,后者会提取未来网页所需的资源,但不会完全预渲染网页,也不会执行 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 公开,同时增强 DevTools 功能,以便更轻松地识别此类极端情况。

预渲染的影响

预渲染可实现几乎即时的页面加载,如以下视频所示:

预渲染的影响示例。

示例网站的加载速度已经很快了,但即便如此,您也可以看到预渲染如何改善用户体验。因此,这还会直接影响网站的核心网页指标,使 LCP 接近零、CLS 降低(因为任何加载 CLS 都发生在初始视图之前),以及 INP 改善(因为加载应在用户互动之前完成)。

即使网页在完全加载之前就激活了,预先开始加载网页应该也会改善加载体验。如果在预渲染仍在进行时激活链接,预渲染页面将移至主框架并继续加载。

不过,预渲染确实会使用额外的内存和网络带宽。请注意,不要过度预渲染,以免消耗用户资源。仅在用户很有可能导航到该网页时预渲染。

如需详细了解如何在 Google Analytics 中衡量实际效果,请参阅衡量效果部分。

查看 Chrome 地址栏的联想查询内容

对于第一个用例,您可以在 chrome://predictors 页面中查看 Chrome 对网址的预测结果:

过滤后的 Chrome 预测器页面,根据输入的文字显示低(灰色)、中(琥珀色)和高(绿色)预测结果。
Chrome“预测器”页面。

绿线表示足够可信,可以触发预渲染。在此示例中,输入“s”时,Chrome 会给出合理的置信度(橙色),但当您输入“sh”时,Chrome 会非常确信您几乎总是会转到 https://sheets.google.com

此屏幕截图是在安装了相对较新的 Chrome 后截取的,并滤除了置信度为 0 的预测结果,但如果您查看自己的预测器,可能会看到更多条目,并且可能需要更多字符才能达到足够高的置信度水平。

这些预测因子也会影响您可能已经注意到的地址栏建议选项:

Chrome 地址栏中的“预测功能”
地址栏“预测功能”

Chrome 会根据您输入的内容和选择不断更新预测器。

  • 如果置信度高于 50%(显示为琥珀色),Chrome 会主动预连接到该网域,但不会预渲染网页。
  • 如果置信度高于 80%(显示为绿色),Chrome 将预渲染网址。

Speculation Rules 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 团队准备了 Speculation Rules Codelab,该 Codelab 将引导您完成向网站添加 Speculation Rules 的操作。

热切

浏览器支持

  • Chrome:121.
  • Edge:121.
  • Firefox:不受支持。
  • Safari:不受支持。

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

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

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

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

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

moderate 选项是一个折衷方案,许多网站都可以从以下推测规则中受益,该规则会在用户将光标悬停在链接上 200 毫秒后或在 pointerdown 事件发生时预渲染链接,是一种基本但强大的推测规则实现:

<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 (FIFO) 2 (FIFO)
Chrome 中的推测限制。

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

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

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

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

此外,在激活之前,Chrome 也不会在预渲染的网页上呈现跨源 iframe。

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

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

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

  • 静态包含的推测规则:例如,如果最新文章是大多数用户的下一个导航目标,新闻媒体网站或博客可能会预渲染该文章。或者,您也可以使用包含 moderateconservative 的文档规则,在用户与链接互动时进行推测。
  • 动态插入的推测规则:这可以基于应用逻辑、根据用户进行个性化设置,也可以基于其他启发词语。

如果您倾向于根据链接上的悬停或点击等操作(许多库过去使用 <link rel=prefetch> 时就采用了这种方式)进行动态插入,建议您查看文档规则,因为这些规则可让浏览器处理您的许多用例。

您可以在主帧的 <head><body> 中添加推测规则。系统不会对子帧中的推测规则执行操作,并且预渲染页面中的推测规则只有在该页面激活后才会执行操作。

Speculation-Rules HTTP 标头

浏览器支持

  • Chrome:121.
  • Edge:121.
  • Firefox:不受支持。
  • Safari:不受支持。

来源

您还可以使用 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) 或应用壳页面不支持。这些架构不使用文档提取,而是对数据或网页进行 API 提取或部分提取,然后对提取的数据进行处理并在当前网页中呈现。应用可以在推测规则之外预提取这些所谓的“软导航”所需的数据,但无法预渲染这些数据。

您可以使用 Speculation Rules 从上一个网页预渲染应用本身。这有助于抵消某些 SPA 的额外初始加载费用。不过,应用内的路线更改无法预渲染。

调试推测规则

如需了解有助于查看和调试此新 API 的 Chrome DevTools 新功能,请参阅专门介绍调试推测规则的博文

多个推测规则

您还可以向同一网页添加多条推测规则,这些规则会附加到现有规则。因此,以下不同的方式都会导致 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.
  • Edge:121.
  • Firefox:不受支持。
  • Safari:不受支持。

来源

预提取或预渲染网页时,某些网址参数(在技术上称为搜索参数)可能对服务器实际传送的网页不重要,并且仅供客户端 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 时才支持。如果用户之前访问过该网站,则系统不会触发推测,并会在 DevTools 中显示失败。

鉴于目前存在的这些限制,一种尽可能改善用户对内部链接和外部链接体验的模式是预渲染同源网址并尝试预加载跨源网址:

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

默认情况下,为防止对跨源链接进行跨源推测而设置的限制对安全至关重要。与 <link rel="prefetch"> 相比,它对跨源目的地进行了改进,后者也不会发送 Cookie,但仍会尝试预加载,这会导致预加载作废,需要重新发送,或者更糟糕的是,导致页面加载不正确。

对于由服务工件控制的页面,不支持使用推测规则进行预加载。我们正在努力添加此支持。请关注此服务工问题支持请求,了解最新动态。Service Worker 控制的页面支持预渲染。

检测 Speculation Rules 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"> 元素:

Google 跟踪代码管理器中的自定义 HTML 代码配置
通过 Google 跟踪代码管理器添加推测规则。

请注意,由于 GTM 不支持 const,因此此示例使用的是 var

取消推测规则

移除推测规则将导致预渲染被取消,但在此发生时,系统可能已耗费资源来启动预渲染,因此如果有可能需要取消预渲染,建议不要预渲染。

推测规则和内容安全政策

由于推测规则使用 <script> 元素,即使它们仅包含 JSON,也需要包含在 script-src Content-Security-Policy 中(如果网站使用此政策,则需要使用哈希或 Nonce)。

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

检测和停用预渲染

预渲染通常能为用户带来良好的体验,因为它可以快速渲染网页(通常是即时渲染)。这对用户和网站所有者都有益,因为预渲染的网页可以提供更好的用户体验,而这在其他情况下可能很难实现。

不过,在某些情况下,您可能不希望预渲染网页,例如,当网页根据初始请求或根据网页上执行的 JavaScript 更改状态时。

在 Chrome 中启用和停用预渲染

预渲染功能仅适用于 chrome://settings/performance/ 中“预加载网页”设置处于启用状态的 Chrome 用户。此外,如果设备内存不足,或者操作系统处于“省流量”或“节能”模式,预渲染功能也会停用。请参阅 Chrome 限制部分。

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

预渲染的网页将随 Sec-Purpose HTTP 标头一起发送:

Sec-Purpose: prefetch;prerender

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

Sec-Purpose: prefetch

服务器可以根据此标头做出响应,以记录推测请求、返回不同的内容或阻止预渲染。如果返回的最终响应代码不成功(即在重定向后不在 200-299 范围内),则系统不会预渲染该网页,并且会舍弃所有预提取网页。另请注意,204 和 205 响应对预渲染无效,但对预提取有效。

如果您不希望预渲染特定网页,返回非 2XX 响应代码(例如 503)是确保不会发生这种情况的最佳方式。不过,为了提供最佳体验,建议改为允许预渲染,但使用 JavaScript 延迟任何仅应在用户实际查看网页时发生的操作。

在 JavaScript 中检测预渲染

在页面预渲染期间,document.prerendering API 将返回 true。网页可以使用此属性在预渲染期间阻止或延迟某些活动,直到网页实际激活。

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

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

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

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

Chrome DevTools 中的控制台,显示了正值 activationStart,表示网页已预渲染
在控制台中测试预渲染。

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

借助这些 API,前端 JavaScript 可以检测预渲染的网页并对其采取适当的措施。

对分析的影响

分析工具用于衡量网站使用情况,例如使用 Google Analytics 衡量网页浏览量和事件。或者,使用 Real User Monitoring (RUM) 衡量网页的性能指标。

只有在用户很可能会加载网页时,才应预渲染网页。因此,只有在这种概率较高(超过 80% 的时间)时,Chrome 地址栏预渲染选项才会出现。

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

为此,您可以使用 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();

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

// 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,因此只有在此之上的内容需要手动阻止。

衡量性能

在衡量性能指标时,分析工具应考虑是根据激活时间还是浏览器 API 报告的网页加载时间来衡量这些指标更好。

对于核心网页指标(由 Chrome 通过 Chrome 用户体验报告衡量),这些指标旨在衡量用户体验。因此,这些指标是根据激活时间衡量的。例如,这通常会导致 LCP 为 0 秒,这表明这是改进核心 Web 指标的绝佳方式。

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

衡量预渲染

您可以通过 PerformanceNavigationTimingactivationStart 条目是否为非零值来判断网页是否已预呈现。然后,您可以在记录网页浏览时使用自定义维度或类似方法记录此维度,例如使用前面介绍的 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 的反馈和分享的使用案例。

致谢

缩略图图片:Unsplash 用户 Marc-Olivier Jodoin