Chrome宣布:于24年3月INP将全面替代FID(相关调研)

Web核心性能指标 及 INP 诞生背景

Web三大性能评价指标:

  • LCP,Largest Contentful Paint,最大内容绘制:是加载性能指标。
  • FID,First Input Delay,首次输入延时,是交互体验指标。
  • CLS,Cumulative Layout Shift,累计布局偏移,是视觉稳定性指标。

分别从不同的维度衡量网络用户访问网页的体验。相关标准阈值可参考:
# 定义核心 Web 指标阈值

但是其中 FID 已知存在一些限制。这促使 Chrome 团队继续探索和寻求反馈,希望找到有助于更有效地解决这些限制的实验性指标(当时)。2022 年,他们宣布将 Interaction to Next Paint (INP) 作为这一新指标,并开始与社区合作测试其有效性。

经过一年的测试并收集社区反馈后,Chrome 团队决定提升 INP 作为核心 Web 指标中的一项新的响应性指标,并从 2024 年 3 月起取代 FID。Chrome 团队的博文详细介绍了这一变更以及新指标背后的原因。

什么是INP?

INP:是Interaction to Next Paint的简写,中文名称与下一次绘制的交互

它是一种网站性能度量指标,用于衡量用户界面的响应性,即网站对用户的交互(如点击或按键)作出反应的速度。

具体而言,它衡量的是用户交互(如点击或按键)后到下次在页面上看到视觉更新之间经过的时间

INP与FID之间的区别?

先来看看一次交互是怎么组成的,一次交互可分为 3 个阶段:

  1. 输入延时(Input Delay)= 交互事件回调开始运行时 - 用户发起与页面的交互时,FID 度量的就是这段时间。
  2. 事件处理(Processing Time)= 事件回调运行完成时 - 事件回调运行开始时
  3. 渲染延时(Presentation Delay)= 浏览器显示包含交互的可视结果的下一帧渲染时 - 事件回调运行完成时

INP与FID之间有两个主要区别:

  • FID仅测量初始处理延迟,即阶段1;而INP测量用户输入和UI更新之间的全部时间,即阶段1~3。

  • FID仅计算页面上的第一次用户交互,而INP会考虑最糟糕的延迟情况。

FID衡量的是浏览器启动处理用户输入所需的时间。它并不包括响应事件或更新UI所花费的实际时间。

正如其名称所示,FID仅考虑用户与页面的首次交互。尤其对于长时间保持打开的页面,比如单页应用程序,这第一次交互可能不能代表整体用户体验。

INP通常衡量页面上最差的输入延迟。谷歌将测量用户交互延迟的第98百分位数。因此,如果页面上的INP为250毫秒,则有2%的用户交互延迟大于250毫秒。

为什么INP可以替代FID ?

在INP被推出之前,FID是衡量web交互体验的核心性能指标。与此同时还存在其他指标(例如TBT(Total Blocking Time)TTL(Time to Interactive)基于长任务,并且与 FID 一样,也测量加载期间的主线程阻塞时间。由于这些指标可以在现场和实验室中测量,许多开发人员会问为什么不选择其中之一而选择FID。

最重要的原因是这些指标并不直接衡量用户体验。所有这些指标都测量页面上运行的 JavaScript 数量。虽然长时间运行的 JavaScript 确实会给网站带来问题,但如果用户在发生问题时没有与页面交互,这些任务不一定会影响用户体验。某个页面可能在 TBT 和 TTI 上得分很高,但感觉很慢。或者得分很低,但用户感觉很快。根据Chrome团队的经验,这些间接测量得出的指标对某些网站来说效果很好,但对大多数网站来说却不太有效。简而言之,长任务和 TTI 不以用户为中心这一事实使得这些候选者(TBT、TTI)表现较弱。

其实在FID的设计之初就已经着手考虑了以下的改进优化,来扩展FID目前的衡量标准: # 迈向更好的响应指标

希望新的指标能够:

  1. 考虑所有用户输入的响应能力(不仅仅是第一个)
  2. 捕获每个事件的完整持续时间(而不仅仅是延迟)。
  3. 将作为同一逻辑用户交互的一部分发生的事件分组在一起,并将该交互的延迟定义为其所有事件的最大持续时间。
  4. 为页面上发生的所有交互创建一个聚合分数,贯穿其整个生命周期。

因此INP作为更全面地度量网站响应性的体验指标,能得以推行,并替代FID。

Chrome 的使用数据显示,用户在页面上花费的时间有 90% 是在页面加载之后,因此,在测量整个页面生命周期的响应度是非常重要的,这就是 INP 诞生的原因。

它不仅仅测量首次交互,而是所有交互延时。除了输入延时,还包括事件处理时长,渲染延时。它的目标是确保从用户开始交互到下一帧绘制的时间尽可能短,以满足用户进行的所有或大多数交互。

它的上报值是整个页面生命周期中最慢的交互延时(取 98%,忽略异常值)。通常来说,一个拥有良好用户体验的网站,它的 INP 应该不超过 200 ms,如果在 200ms - 500ms 之间,则需要改进,大于 500ms,代表页面响应性很差。为了确保大多数用户都能达到这个目标,我们可以观测 75 分位的 INP。

INP 代表的是更准确的网站响应性体验。

标准变更之后对于前端的影响

经过以上分析可以得知,原有的FID指标是INP指标中的一部分。完善并丰富了用户交互体验的衡量指标。

因此如果原有网页对FID有很好的优化的话,接入新的CWV(Core Web Vitals)指标(INP)作为页面体验性能评价指标,并不会带来任何障碍,相反为INP的体验优化提供了很好的基础。

如何测量INP?

有了上面的理论知识,我们还需要对自己的网站有一个更加深入的了解.所以,我们就需要借助科技的力量来对目标网站进行诊断处理.

我们可以使用多种工具来测量INP,例如:

除此之外,开发者还可以打开Chrome浏览器调试工具的lighthouse,勾选Timespan, 点击"Start Timespan"生成相应的网页交互评价报告。

如何优化网页的INP指标?

减少输入延时

每个交互都以一定量的输入延时开始。

一些输入延时是不可避免的,比如操作系统识别输入事件并将其传递给浏览器总是需要一些时间。但一些输入延时是可以避免的。

  1. 避免反复执行的定时器占用主线程工作

JavaScript 中有两个常用的定时器可能导致输入延时:setTimeout 和 setInterval。

  • setTimeout 本身并没有问题,甚至有助于避免 long task。但是,如果在 timeout 后的回调运行时,用户刚好在尝试与页面交互,就可能导致输入延时。应该避免 setTimeout 循环或递归地执行,让其行为变得像 setInterval,同时应该注意确保在它的回调里不会执行过多的工作。
  • 而 setInterval 在一个 interval 时间间隔上运行回调,因此更有可能阻碍交互。
  1. 避免 longt task

在交互过程中,如果执行的 task 过长,阻塞了主线程时,就会增加输入延时。

所以,应该尽量减少一项 task 中的工作量,在主线程上做尽可能少的工作,还可以通过分解 long task 来提高对用户输入的响应能力。

  1. 注意交互重叠(interaction overlap)

这是优化 INP 的一个特别具有挑战性的部分。交互重叠指的是,当在用户首次完成交互后,有机会渲染包含该交互可视结果时,又产生了新的交互。

交互重叠的来源很简单,可能是用户在短时间内进行了多次交互,比如用户输入表单字段时。如果在输入完成后要进行的交互开销很大,一个常见的场景是会发送网络请求到后端。

面对这种场景我们可以使用 debounce 限制在事件回调在时间段内执行的次数,也可以取消掉上次发出的请求,这样主线程就不用处理那么多的事件回调。

另一个交互重叠增加输入延时的场景是昂贵的动画。因为这会触发很多的 requestAnimationFrame 阻塞交互。我们应该尽可能地使用 CSS 动画,并且使用合成层动画,让动画运行在GPU和合成器线程上,而不是主线程。

优化事件回调

输入延时只是 INP 测量的第一部分。还需要确保响应用户交互而运行的事件回调可以尽快完成。

  1. 优化 long task

提高事件处理速度,尽快让出主线程。

  1. 建立正确的输入优先级

通对不同类型的输入进行分类,建立优先级顺序,例如首选输入、次要输入和可等待输入。

首选输入应该尽可能快地得到响应,而次要输入和可等待输入可以稍后处理。

比如 React 18 新引入的 API useDeferredValueuseTransition 就是用来做这个的,让 value 的更新和回调的执行不阻塞 UI。

  1. 避免布局抖动

布局抖动,又叫强制同步布局,是一种渲染问题,会造成性能瓶颈。

问题产生的原因就是在同一个任务中,更新了样式,然后立即使用 JavaScript 读取这些新样式,让浏览器被迫做同步的布局工作。

减少渲染延时

交互的渲染延时表示从交互的事件回调运行完成到浏览器能够绘制下一帧显示结果的时间段。

  1. 减小 DOM 当 DOM 很小时,渲染工作完成的会比较快。可以采取一些办法减小 DOM 的大小,比如使用虚拟列表来避免 DOM 过大,但这样的方法可能效果有限。
  2. 使用 content-visibility 属性延时渲染视口外的元素

这个 CSS 属性可以控制元素在接近视口时才会被渲染,目前还属于实验性属性,在一些浏览器上还不兼容。但确实能有效减少渲染延时,改善 INP。

对于现有业务可能的拓展与促进

本次参加Google开发者大会,了解到 Miravia (阿里在欧洲的电商平台) 会针对每次构建后的线上产物进行性能监控,同时建立阈值,每次迭代发布后,如果其中某个重要指标下降百分比超过了设定的阈值,则会有相应的报警,来协助保持页面的可访问性以及访问体验。

因此,针对重要项目,可以考虑在项目中引入 web-vitals 将INP等重要指标进行上报,并且建立监控告警。可以协助业务的稳定健康发展。

例如:

如果我们想使用JavaScript编程来测量INP,可以使用web-vitals库。这使我们可以从真实用户那里获取测量数据。

我们可以使用如下的script标签加载该库:

html 复制代码
<script src="https://unpkg.com/web-vitals@3/dist/web-vitals.iife.js">

然后,我们可以使用webVitals对象上的onINP方法来查看INP值何时发生变化。

js 复制代码
webVitals.getINP(function(info) {
   console.log(info)
}, {reportAllChanges: true});

INP指标的值可能会在页面的生命周期内随着用户不断与其进行交互而发生变化。reportAllChanges确保即使是初步值也会被报告。

除了报告INP值外,web-vitals库还会报告一个条目列表。这些条目是导致INP分数异常的个别用户交互。

json 复制代码
{
    "name": "pointerdown",
    "entryType": "first-input",
    "startTime": 20168.80000001192,
    "duration": 8,
    "processingStart": 20176.30000001192,
    "processingEnd": 20176.5,
    "cancelable": true,
    "target": "(DOM Element Object)"
}
  • target字段告诉我们用户与哪个页面元素进行了交互。
  • startTime字段是用户交互发生时的时间戳,单位为毫秒。
  • processingStart字段表示事件处理程序开始运行的时间。
  • processingEnd字段表示事件处理已完成的时间。

将以上数据,结合数据上报和监控报警工具来实现对重要业务的性能监控与追踪。

INP的交互适用范围及其局限性

以下交互会被计入INP

  • 鼠标点击
  • 触摸(在触摸屏上)
  • 键盘按键

以下交互不会被计入:

  • 悬停
  • 滚动

INP 度量的是用户在页面上操作全程的响应性能,更贴近用户实际执行时的体验,但同时也有一些局限。

SPA 的路由跳转,也算作「交互」

在单页应用(SPA)中,路由的跳转,也会被算作了「交互」,而不是「导航」。

而用户对于两种不同的行为有着不同的预期,对于「导航」而言一般用户可以忍受超过比普通点击更长的延迟。

SPA 跨页面上报

这其实是目前 Web 指标的通病。同一个应用不同页面的 INP 会混在一起上报,但可能在使用过程中某个页面其实 INP 是比较小的,或者上报时的 INP 是之前使用的页面而不是上报的页面导致的。

INP指标对于安卓等其他终端是否适用?

由于INP指标是基于web交互体验推出的评价指标,暂未找到相关佐证论述该指标可以用作其他终端体验的评价体系,但是INP所囊括的交互时间(Input Delay + Processing Time + Presentation Delay)是从交互的三个阶段来划分的,因此对于其他终端的评价体系而言是具有一定的参考价值的。

参考文档:

# Interaction to Next Paint (INP) # Advancing Interaction to Next Paint
# INP 即将代替 FID 成为新的核心 Web 指标
# Towards a better responsiveness metric
# 浏览器之性能指标-INP
# Feedback wanted: An experimental responsiveness metric
# 定义核心 Web 指标阈值
# First Input Delay(FID):什么是FID以及如何优化你的WordPress网站

相关推荐
小小竹子几秒前
前端vue-实现富文本组件
前端·vue.js·富文本
小白小白从不日白9 分钟前
react hooks--useReducer
前端·javascript·react.js
下雪天的夏风21 分钟前
TS - tsconfig.json 和 tsconfig.node.json 的关系,如何在TS 中使用 JS 不报错
前端·javascript·typescript
diygwcom33 分钟前
electron-updater实现electron全量版本更新
前端·javascript·electron
Hello-Mr.Wang1 小时前
vue3中开发引导页的方法
开发语言·前端·javascript
程序员凡尘1 小时前
完美解决 Array 方法 (map/filter/reduce) 不按预期工作 的正确解决方法,亲测有效!!!
前端·javascript·vue.js
编程零零七5 小时前
Python数据分析工具(三):pymssql的用法
开发语言·前端·数据库·python·oracle·数据分析·pymssql
(⊙o⊙)~哦7 小时前
JavaScript substring() 方法
前端
无心使然云中漫步7 小时前
GIS OGC之WMTS地图服务,通过Capabilities XML描述文档,获取matrixIds,origin,计算resolutions
前端·javascript
Bug缔造者7 小时前
Element-ui el-table 全局表格排序
前端·javascript·vue.js