衡量软导航

发布时间:2023 年 2 月 1 日;上次更新时间:2026 年 9 月 2 日

Browser Support

  • Chrome: 151.
  • Edge: 151.
  • Firefox: not supported.
  • Safari: not supported.

Source

自推出以来,Core Web Vitals 计划一直致力于衡量网站的实际用户体验,而不是网站的创建或加载方式背后的技术细节。这三项 Core Web Vitals 指标是以用户为中心的指标,是现有技术指标(例如 DOMContentLoadedload)的改进,这些技术指标衡量的时间往往与用户感知到的网页性能无关。因此,只要网站表现良好,用于构建网站的技术就不应影响得分。

现实情况总是比理想情况复杂一些,而热门的单页应用架构从未获得核心网页指标的完全支持。当用户在网站中浏览时,这些 Web 应用不会加载不同的单个网页,而是使用所谓的“软导航”,即通过 JavaScript 更改网页内容。在这些应用中,通过更改网址并将之前的网址推送到浏览器的历史记录中,可以保持传统网页架构的假象,从而让后退和前进按钮能够按用户预期的方式工作。

许多 JavaScript 框架都使用此模型,但每种框架的使用方式各不相同。由于这超出了浏览器传统上所理解的“网页”范围,因此一直难以衡量:如何界定当前网页上的互动,又如何将其视为网页?

Chrome 团队已经考虑此挑战有一段时间了,目前正寻求标准化“软导航”的定义,以及如何针对软导航衡量核心网页指标,就像衡量以传统多网页应用 (MPA) 架构实现的网站一样。

我们根据开发者的反馈对提案进行了多项改进,并从 Chrome 151 开始推出了两项新的性能 API,以帮助解决此问题。

什么是软导航?

我们提出了以下关于软导航的定义:

  • 导航由用户操作发起。
  • 导航会导致用户看到的网址发生变化。
  • 互动会导致可见的绘制。

对于某些网站,此定义可能会导致出现假正例(用户实际上不会认为发生了“导航”)或假负例(用户认为发生了“导航”,但实际上不符合这些条件)。欢迎您在软导航规范代码库中提供反馈。

开发者工具对软导航的支持

我们已在 Live Metrics 视图和具有洞察和标记支持的轨迹视图中,为开发者工具的性能面板添加了对软导航的支持:

开发者工具对软导航的支持。

Chrome 如何为 Web 开发者实现软导航?

启用软导航功能后(下一部分会详细介绍),Chrome 将更改其报告某些性能指标的方式:

  • 每次检测到软导航后,系统都会发出 soft-navigation PerformanceTiming 事件。
  • soft-navigation 条目将包含 navigationIdname 属性中的新网址以及启动互动的 interactionId
  • 在导致有内容绘制的互动之后,系统会发出一个或多个 interaction-contentful-paint 条目。此对象将包含一个 largestContentfulPaint 条目,可用于衡量软导航的 Largest Contentful Paint (LCP)
  • navigationId 属性已添加到每个性能时间(first-paintfirst-contentful-paintlargest-contentful-paintinteraction-contentful-paintfirst-input-delayeventlayout-shift)。这对应于发出事件时所处的导航条目。请注意,如果这些条目跨越软导航,则可能会包含上一个或下一个 navigationId,具体取决于条目的发出时间。如需详细了解此方面的信息,请参阅针对相应网址报告指标部分。
  • soft-navigation 将包含一个 getLargestInteractionContentfulPaint() 函数,用于检索相应导航的最大 interaction-contentful-paint 条目。然后,该值可用作相应导航的初始 LCP,并且随着观察到该互动的更多 interaction-contentful-paint 条目,该 LCP 随后可以更新。请注意,此属性会替换之前源试用中提供的 largestInteractionContentfulPaint 属性。
  • 在软导航发生之前,可能已经发生了一些 interaction-contentful-paint 条目(如果网址更新直到这些绘制之后才发生)。在这种情况下,getLargestInteractionContentfulPaint() 函数可避免在软导航完成后缓冲并回顾旧条目。请注意,getLargestInteractionContentfulPaint() 返回的条目是发出时最大 interaction-contentful-paint 条目的精确副本,因此该条目可能使用了之前的 navigationId,因为这是发生绘制的时间,但这些绘制应根据新的 navigationId 进行衡量。
  • soft-navigation 条目还将包含 paintTimepresentationTime 作为相应导航的 FCP。
  • 请注意,在进一步互动后,系统也会发出 interaction-contentful-paint 条目,但网址的 LCP 应仅限于与软导航 interactionId 匹配的 interaction-contentful-paint 条目,以排除这些条目,并且仅限于其中的 largestContentfulPaint 属性。

这些更改将允许按每次网页导航来衡量 Core Web Vitals 和一些相关的诊断指标,不过有一些细微差别需要考虑。

在 Chrome 中启用软导航会带来哪些影响?

启用此功能后,网站所有者需要考虑以下一些变化:

  • 通过监控 soft-navigation 条目,可以将效果条目“切分”为每个“导航”。
  • CLS 和 INP 指标已经可以根据您的意愿进行切分,而不是在整个网页生命周期内进行衡量,但软导航功能提供了一种标准化衡量方式,无论使用何种底层技术,都可以衡量这种情况何时发生。
  • largest-contentful-paint 条目在互动时最终确定(这是启动软导航所必需的),因此只能用于衡量初始“硬”导航 LCP。这意味着,在衡量软导航时,此设置不会发生变化,因此可以像以前一样衡量初始硬导航的网页加载 LCP。
  • 通过查看交互中发出的新 interaction-contentful-paint 条目中的 largestContentfulPaint 属性,可以衡量软导航的 LCP,但使用此条目时需要考虑一些事项,我们将在本文中讨论这些事项。
  • 请注意,并非所有用户都支持此软导航功能,尤其是使用其他浏览器或 Chrome 151 之前版本的用户。请注意,即使某些用户会报告 Core Web Vitals 指标,他们也可能不会报告基于软导航的指标。

请咨询您的 RUM 提供商,了解他们是否支持通过软导航来衡量核心网页指标。许多人正计划测试这一新标准,并将之前的注意事项纳入考虑范围。与此同时,部分提供商还允许根据自己的启发式方法对效果指标进行有限的衡量。

如需详细了解如何衡量软导航的指标,请参阅按软导航衡量 Core Web Vitals 部分

如何在 Chrome 中启用软导航?

自 Chrome 151 起,软导航功能默认处于启用状态。

检测软导航 API 支持的功能

您可以使用以下代码来测试是否支持该 API:

if (PerformanceObserver.supportedEntryTypes.includes('soft-navigation')) {
  // Monitor Soft Navigations
}

或者:

if ('SoftNavigationEntry' in window) {
  // Monitor Soft Navigations
}

如何衡量软导航?

在支持的情况下,这些指标可使用 PerformanceObserver API 进行报告,与其他指标一样。不过,对于这些指标,还需要考虑一些额外因素。

报告软导航

您可以使用 PerformanceObserver 来观察软导航。以下是一个示例代码段,用于将软导航条目记录到控制台,包括使用 buffered 选项记录此页面上之前的软导航:

const observer = new PerformanceObserver(console.log);
observer.observe({ type: "soft-navigation", buffered: true });

可用于最终确定上一次导航的完整生命周期页面指标。

针对相应网址报告指标

检测到软导航时,应最终确定上一个网页的 Core Web Vitals,然后针对上一个网址报告这些指标,并针对新网址开始新的监控。

相应 soft-navigation 条目的 name 属性将包含用于报告指标的新网址,而 navigationId 将是相应导航的唯一引用(因为在单页应用的生命周期内,同一网址可能会被多次访问)。

此值应设置为每个 soft-navigation 条目,并用于报告指标,直到收到下一个 soft-navigation 条目。

报告 interaction-contentful-paint 的正确网址

interaction-contentful-paint 条目计算 LCP 时需要考虑一些额外因素,因为并非所有 interaction-contentful-paint 条目都应使用 navigationId 进行映射并作为相应网址的 LCP 进行报告:

  • 第一个问题是,如果在网址更新之前发生绘制,则可能会在软导航发生之前发出 interaction-contentful-paint 条目。在这种情况下,navigationId 将是旧网址。如果先更新网址,然后完成绘制,则会完成软导航,在这种情况下,系统会先发出 soft-navigation 条目,而 interaction-contentful-paint 将包含新网址。
  • 第二个问题是,interaction-contentful-paint 条目将继续针对较新的互动发出,因为此效果指标的范围不仅限于软导航的 LCP。我们只想考虑 LCP 的软导航加载的绘制,而不考虑后续互动的绘制。

因此,应使用 interactionId 而不是 navigationIdinteraction-contentful-paint 条目映射到 soft-navigation-entries,以获取正确的网址。这样一来,不仅可以处理具有旧 navigationId 的所有条目,还可以滤除不应纳入 LCP 考虑范围的所有 interaction-contentful-paint 条目。

此外,您应先处理 soft-navigation 条目的 getLargestInteractionContentfulPaint() 函数,以处理在发出 soft-navigation entries 之前发生的 interaction-contentful-paint 条目。

获取软导航的 startTime

所有性能时间(包括软导航的时间)以及用于计算 Core Web Vitals 指标的条目都报告为自初始“硬”网页导航时间起的时间。因此,应从软导航加载指标时间(例如 LCP)中减去软导航开始时间,以便报告相对于此软导航时间的值。

通过映射到相应的 soft-navigation 条目并使用其 startTime,可以类似地获取导航开始时间。

startTime 是启动软导航的初始互动(例如点击按钮)的时间。这与“硬导航”略有不同,在“硬导航”中,“开始时间”是指浏览器“提交”新网页的时间,并且是在运行部分事件处理脚本代码之后。由于我们是从互动开始时间开始测量的,因此软导航开始时间也包括该事件处理程序代码。

衡量每次软导航的 Core Web Vitals

如需衡量 Core Web Vitals,请监听 soft-navigation 条目,并在收到这些条目时重置指标。可以根据 presentationTime 发出 FCP,并将 LCP 初始化为 getLargestInteractionContentfulPaint() 条目。INP、CLS 应初始化为 0,就像网页加载时一样。

然后,您可以像往常一样衡量和监控 LCP、INP 和 CLS(使用 interaction-contentful-paint 时,LCP 提供 interactionId 匹配项的情况除外)。interactionId 可用于命名网址的条目,如前文所述

时间仍将相对于原始的“硬”导航开始时间返回。因此,若要计算软导航的 LCP,您需要获取 interaction-contentful-paint 时间,然后减去相应的软导航开始时间(如前文所述),以获得相对于软导航的时间。

有些指标一直以来都是在整个网页生命周期内进行衡量的:例如,LCP 在发生互动之前可能会发生变化。在离开网页之前,无论是否发生任何互动,CLS 和 INP 都可以更新。因此,每次发生新的软导航时,都应最终确定上一次导航的指标。这意味着,如果使用软导航来衡量 Core Web Vitals,初始“硬”导航指标可能会比平时更早确定。

同样,当开始衡量这些长期存在的指标的新软导航的指标时,需要“重置”或“重新初始化”指标,并将其视为新指标,而不会记住之前“网页”设置的值。也就是说,系统会重置对“最大”绘制、Interaction to Next Paint 或布局偏移的理解,以便从头开始重新衡量。

在导航之间保持不变的内容应如何处理?

软导航的 LCP(根据 interaction-contentful-paint 计算)将仅衡量新绘制,并且仅衡量与导致导航的互动相关联的绘制。这可能会导致从该软导航的冷加载到软加载的 LCP 不同。

例如,假设某个网页包含一个作为 LCP 元素的大横幅图片,但其下方的文字会随着每次软导航而变化。初始网页加载会将横幅图片标记为 LCP 元素,并以此为基础确定 LCP 时间。对于后续的软导航,下面的文字将是软导航后绘制的最大元素,并将成为新的 LCP 元素。不过,如果网页是通过软导航网址中的深层链接加载的,则横幅图片将是新的绘制,因此可以被视为 LCP 元素。

同样,动画可能会持续更新网页的一部分,而这与发生的任何软导航无关。由于该背景动画而产生的所有新绘制操作都不会被视为新软导航的 LCP。不过,如果网页是从此网址重新加载的,则可能会将这些图片纳入 LCP 考虑范围。

如这些示例所示,软导航的 LCP 元素的报告方式可能会因网页的加载方式而异,就像加载带有锚链接的网页(锚链接位于网页下方)可能会导致硬导航的 LCP 元素有所不同一样。

如何衡量 TTFB?

对于常规网页加载,第一字节时间 (TTFB) 表示返回原始请求的第一个字节所用的时间。

对于软导航,这是一个比较棘手的问题。我们是否应衡量针对新网页发出的第一个请求?如果应用中已包含所有内容,并且没有其他请求,会发生什么情况?如果提前通过预提取发出该请求,会怎么样?如果用户发出的请求与软导航无关(例如,是分析请求),会发生什么情况?

一种更简单的方法是,对于软导航,报告的 TTFB 为 0,这与我们建议的往返缓存恢复类似。这是 web-vitals用于软导航的方法,也是我们目前建议用于此指标的方法。

您是否应该同时使用这两种方法来衡量 Core Web Vitals?

虽然这些新 API 仅限于基于 Chromium 的浏览器,但网站可能希望通过按软导航进行切分来衡量这两者,并继续按硬导航进行切分。这样就可以跨浏览器进行比较,并查看历史趋势。

对于 LCP,这意味着当前方式只考虑 largest-contentful-paint 条目,而新方式同时考虑 largest-contentful-paintinteraction-contentful-paint 条目。

对于 CLS 和 INP,这意味着像当前那样在整个网页生命周期内衡量这些指标,并按软导航分别对时间轴进行切分,以衡量新指标的单独 CLS 和 INP 值。

然后,这些指标需要信标化并存储两次以供分析。

使用 web-vitals 库衡量软导航的 Core Web Vitals

要考虑所有细微差别,最简单的方法是使用 web-vitals JavaScript 库,该库自 v6.0.0 起支持软导航。您可以通过以下方式衡量此指标(根据需要替换 doTraditionalProcessingdoSoftNavProcessing):

import {
  onTTFB,
  onFCP,
  onLCP,
  onCLS,
  onINP,
} from 'https://unpkg.com/web-vitals@soft-navs/dist/web-vitals.js?module';

function doTraditionalProcessing(callback) {
  ...
}

function doSoftNavProcessing(callback) {
  ...
}

onTTFB(doTraditionalProcessing);
onFCP(doTraditionalProcessing);
onLCP(doTraditionalProcessing);
onCLS(doTraditionalProcessing);
onINP(doTraditionalProcessing);

onTTFB(doSoftNavProcessing, {reportSoftNavs: true});
onFCP(doSoftNavProcessing, {reportSoftNavs: true});
onLCP(doSoftNavProcessing, {reportSoftNavs: true});
onCLS(doSoftNavProcessing, {reportSoftNavs: true});
onINP(doSoftNavProcessing, {reportSoftNavs: true});

web-vitals 库还可确保您报告的指标是针对正确的网址报告的(如前所述),因为它们在提供给回调的条目中同时包含 navigationIdnavigationURL

web-vitals 库会针对软导航报告以下指标:

指标 详细信息
TTFB 报告为 0。
首次内容渲染 (FCP) 相对于触发软导航的互动所对应的软导航开始时间,首次内容绘制的时间。系统不会考虑上一次导航中存在的或与互动无关的现有绘制。
LCP 从触发软导航的互动开始,到发生 Largest Contentful Paint 的时间(相对于软导航开始时间)。之前导航中存在的现有绘制不与互动相关联,因此不予考虑。与往常一样,此值可以继续更新,直到用户离开网页(或软导航),因为只有这样才能最终确定 LCP。
INP 导航时间之间的 INP。与往常一样,此指标可以继续更新,直到用户离开相应网页(或软导航)为止,因为只有到那时,INP 才能最终确定。如果没有互动,则不会报告 0 值。请注意,导致软导航的互动通常与之前的导航(正在从中导航)相关联,而不是与新的导航(正在导航到)相关联,因为需要首次渲染才能导致软导航。这类似于硬导航,即链接点击可能具有 INP,但该 INP 会与发生点击的网页相关联。
CLS 导航时间之间最大的班次窗口。与往常一样,此指标可以继续更新,直到用户离开网页(或软导航),因为只有这样才能最终确定 CLS。请注意,与导航事件关联的 CLS 可能会被排除(如果发生在互动后的 500 毫秒内),可能会与之前的导航关联(如果位移发生在网址更新之前),也可能会与新的导航关联(如果位移发生在软导航完成之后)。

这些更改是否会纳入 Core Web Vitals 的衡量范围?

最终目的是提供一种方法,以便更好地衡量真实用户的体验效果。因此,我们的目标是在 API 推出后,将这些指标纳入所有工具显示的核心网页指标衡量结果中。

CrUX 中将如何报告软导航?

此功能推出后,CrUX 中将如何确切报告软导航,目前也尚未确定。当我们有更多信息可分享时,会在此处公布 CrUX 的变化。

如何在其他浏览器中处理软导航?

在不支持该 API 的浏览器中,很难以编程方式检测软导航,而这正是我们开发该 API 的原因。

您可以使用 Navigation API 监控网址变化,这可能允许按网址对 INP 进行切分(同样适用于 CLS,不过目前 CLS 仅限 Chromium,因此无论如何都不会进行衡量)。不过,这无法解决只能近似计算的绘制指标(FCP 和 LCP)。

与此同时,我们认为此 API 提供的分析洞见非常宝贵,不容忽视,无论是在衡量软导航的时间,还是在将指标归因于正确的导航方面,都是如此。尽管目前该 API 尚不支持跨浏览器,但我们仍建议您使用此新 API。与 Core Web Vitals 推出时类似,即使目前仅基于 Chromium 的浏览器会显示已发现的问题和性能解决方案,这些问题和解决方案也可能会影响所有浏览器。

我们将继续推进标准化流程,并与其他浏览器供应商沟通,以展示此 API 的重要性。

反馈

我们正在积极征求有关此 API 的反馈,您可以在以下位置提供反馈:

如果您有疑问,也不必过于担心,我们很乐意在任一位置收到您的反馈,并会乐于在两个位置对问题进行分诊,然后将问题重定向到正确的位置。

更新日志

在开发此 API 的过程中,它发生了一些变化,比稳定版 API 的变化更多。如需了解详情,请参阅软导航变更日志

总结

软导航功能是一种令人兴奋的方法,可用于了解 Core Web Vitals 计划如何发展,以衡量现代网络上我们指标中缺失的常见模式。我们从更广泛的 Web 社区收集了大量反馈,并对该 API 的潜力感到鼓舞。

致谢

缩略图图片由 Unsplash 用户 Jordan Madrid 提供

这项工作是 Yoav Weiss 在 Google 时首次开展的工作的延续。感谢 Yoav 为此 API 付出的努力。