我们都知道给对方留下良好的第一印象非常重要。这在结识新朋友时很重要,在构建 Web 体验时也很重要。
在网络上,良好的第一印象可能会决定用户是成为忠实用户,还是离开并永远不会回来。问题在于,什么是良好的印象?您如何衡量自己可能会给用户留下什么样的印象?
在网络上,第一印象可以有很多不同的形式,我们对网站的设计和视觉吸引力有第一印象,对其速度和响应能力也有第一印象。
虽然很难衡量用户对网站设计的喜爱程度,但衡量网站的速度和响应能力却很容易!
您可以通过 First Contentful Paint (FCP) 衡量用户对您网站加载速度的第一印象。但网站能够将像素绘制到屏幕的速度只是其中一部分。同样重要的是,当用户尝试与这些像素互动时,您的网站的响应速度如何!
First Input Delay (FID) 指标有助于衡量用户对您网站互动性和响应速度的第一印象。
什么是 FID?
FID 用于衡量从用户首次与网页互动(即点击链接、点按按钮或使用由 JavaScript 提供支持的自定义控件)到浏览器实际能够开始处理事件处理脚本以响应该互动的时间。
FID 得分怎样才算理想?
为了提供良好的用户体验,网站应尽量将首次输入延迟时间控制在 100 毫秒以内。为确保大多数用户都能达到此目标值,一个合适的衡量阈值是网页加载时间的第 75 个百分位数,并按移动设备和桌面设备进行细分。
详细了解 FID
作为编写响应事件的代码的开发者,我们通常假定我们的代码会在事件发生后立即运行。但作为用户,我们都经常遇到相反的情况:在手机上加载网页后,尝试与之互动,但却发现什么都没有发生,这会令人沮丧。
通常,输入延迟(也称为输入延迟时间)是由于浏览器的主线程正忙于执行其他操作,因此无法(尚未)响应用户。导致这种情况的一个常见原因是,浏览器正忙于解析和执行应用加载的大型 JavaScript 文件。在执行此操作时,它无法运行任何事件监听器,因为它所加载的 JavaScript 可能会指示它执行其他操作。
请考虑以下典型网页加载时间轴:
上图显示了一个网页正在发出对资源(很可能是 CSS 和 JS 文件)的多个网络请求,这些资源在下载完成后会在主线程中进行处理。
这会导致主线程暂时处于繁忙状态,这由米色任务块表示。
首次输入延迟时间过长通常发生在 First Contentful Paint (FCP) 和 Time to Interactive (TTI) 之间,因为网页已渲染部分内容,但尚未可靠地实现交互。为了说明这种情况是如何发生的,我们在时间轴中添加了 FCP 和 TTI:
您可能已经注意到,FCP 和 TTI 之间有相当长的时间(包括三个长任务),如果用户在此期间尝试与网页互动(例如点击链接),则在收到点击和主线程能够响应之间会出现延迟。
考虑一下,如果用户尝试在最长任务开头附近与网页互动,会发生什么情况:
由于输入发生在浏览器运行任务期间,因此它必须等到任务完成才能响应输入。它必须等待的时间就是此用户在此网页上的 FID 值。
如果互动没有事件监听器,会怎么样?
FID 用于衡量收到输入事件与主线程下次空闲之间的时间差。这意味着,即使未注册事件监听器,系统也会衡量 FID。原因在于,许多用户互动不需要事件监听器,但需要主线程处于空闲状态才能运行。
例如,以下所有 HTML 元素都需要等待主线程上的进行中的任务完成,然后才能响应用户互动:
- 文本字段、复选框和单选按钮 (
<input>
、<textarea>
) - 选择下拉菜单 (
<select>
) - 链接 (
<a>
)
为什么只考虑第一个输入?
虽然任何输入延迟都可能会导致用户体验不佳,但出于以下几点原因,我们主要建议您衡量首次输入延迟:
- 首次输入延迟是用户对您网站响应速度的第一印象,而第一印象对于我们形成对网站质量和可靠性的总体印象至关重要。
- 目前,网络上最严重的交互性问题出现在网页加载期间。因此,我们认为,最初专注于提升网站的首次用户互动体验,对提升网站的整体互动性影响最大。
- 针对网站如何解决首次输入延迟时间过长问题(代码分块、预加载较少的 JavaScript 等)推荐的解决方案,不一定适用于解决页面加载后输入延迟缓慢的问题。通过将这些指标分开,我们将能够向 Web 开发者提供更具体的性能指南。
什么会被计为第一个输入?
FID 是一项指标,用于衡量网页在加载期间的响应能力。因此,它仅关注点击、点按和按键等离散操作的输入事件。
滚动和缩放等其他互动是连续操作,具有完全不同的性能限制(此外,浏览器通常能够通过在单独的线程中运行这些操作来隐藏其延迟时间)。
换句话说,FID 侧重于 RAIL 性能模型中的 R(响应能力),而滚动和缩放与 A(动画)更相关,因此应单独评估它们的性能质量。
如果用户从未与您的网站互动,该怎么办?
并非所有用户每次访问您的网站都会与您的网站互动。并非所有互动都与 FID 相关(如前面部分所述)。此外,某些用户的首次互动会发生在不好的时机(主线程长时间处于繁忙状态),而某些用户的首次互动会发生在好时机(主线程完全空闲)。
这意味着,有些用户将没有 FID 值,有些用户的 FID 值较低,有些用户的 FID 值可能较高。
与您可能习惯的其他指标相比,跟踪、生成报告和分析 FID 的方式可能大不相同。下一部分将介绍最佳实践。
为什么只考虑输入延迟?
如上所述,FID 仅衡量事件处理中的“延迟时间”。它不会衡量事件处理总时长本身,也不会衡量浏览器在运行事件处理脚本后更新界面所需的时间。
虽然此时间对用户很重要,并且确实会影响体验,但此指标并未将其包含在内,因为这样做可能会促使开发者添加实际上会降低体验的权宜解决方法,即他们可能会将事件处理脚本逻辑封装在异步回调中(通过 setTimeout()
或 requestAnimationFrame()
),以将其与与事件关联的任务分离。结果是指标得分会有所提高,但用户会感受到响应速度变慢。
不过,虽然 FID 仅衡量事件延迟时间的“延迟”部分,但如果开发者想要跟踪更多事件生命周期,则可以使用 Event Timing API。如需了解详情,请参阅自定义指标指南。
如何衡量 FID
FID 是一个只能在现场衡量的指标,因为它需要真实用户与您的网页互动。您可以使用以下工具衡量 FID。
现场工具
在 JavaScript 中衡量 FID
如需在 JavaScript 中衡量 FID,您可以使用 Event Timing API。以下示例展示了如何创建一个监听 first-input
条目的 PerformanceObserver
,并将其记录到控制台:
new PerformanceObserver((entryList) => {
for (const entry of entryList.getEntries()) {
const delay = entry.processingStart - entry.startTime;
console.log('FID candidate:', delay, entry);
}
}).observe({type: 'first-input', buffered: true});
在上面的示例中,first-input
条目的延迟时间值是通过计算条目的 startTime
和 processingStart
时间戳之间的差值来衡量的。在大多数情况下,这将是 FID 值;不过,并非所有 first-input
条目都适用于衡量 FID。
以下部分列出了 API 报告的内容与指标计算方式之间的差异。
指标与 API 之间的差异
- 该 API 会为在后台标签页中加载的网页分派
first-input
条目,但在计算 FID 时应忽略这些网页。 - 如果网页在发生首次输入之前处于后台状态,API 也会调度
first-input
条目,但在计算 FID 时也应忽略这些网页(仅当网页在整个时间都处于前台状态时,才会考虑输入)。 - 从返回/前进缓存恢复网页时,该 API 不会报告
first-input
条目,但在这些情况下,应衡量 FID,因为用户会将其视为不同的网页访问。 - 该 API 不会报告在 iframe 中发生的输入,但该指标会报告,因为这些输入是网页用户体验的一部分。这可能会导致 CrUX 和 RUM 之间出现差异。为了准确衡量 FID,您应考虑这些因素。子帧可以使用此 API 将其
first-input
条目报告给父帧以进行汇总。
分析和报告 FID 数据
由于 FID 值存在预期的差异,因此在报告 FID 时,请务必查看值的分布情况,并重点关注较高的百分位数。
虽然所有 Core Web Vitals 阈值的百分位数选择都是第 75 百分位,但我们仍强烈建议您特别关注 FID 的第 95-99 百分位,因为这些百分位数对应于用户在您的网站上获得的特别糟糕的初次体验。并会显示最需要改进的方面。
即使您按设备类别或类型细分报告,也是如此。例如,如果您为桌面设备和移动设备分别生成报告,那么您在桌面设备上最关注的 FID 值应为桌面设备用户的第 95-99 百分位数,您在移动设备上最关注的 FID 值应为移动设备用户的第 95-99 百分位数。
如何提高 FID
您可以参阅有关优化 FID 的完整指南,了解改进此指标的技巧。
更新日志
有时,我们会在用于衡量指标的 API 中发现 bug,有时也会在指标本身的定义中发现 bug。因此,有时必须进行更改,这些更改可能会在内部报告和信息中心中显示为改进或回归。
为帮助您管理这些指标,我们会在此更新日志中显示对这些指标的实现或定义所做的所有更改。
如果您对这些指标有任何反馈,可以通过 web-vitals-feedback Google 群组提供反馈。