译:什么是 INP

原文:https://blog.sentry.io/what-is-inp/
作者:Salma Alam-Naylor
译者:ChatGPT 4 Turbo

编者注:一些收获。1)INP 全称是 Interaction to Next Paint,2)通过 Chrome DevTool 的 Performance Tab 可以发现 INP 问题,200ms 以上的需要提高,3)有新的 API 可以改善 INP,比如 navigator.scheduling.isInputPending() 和 scheduler.yield,4)一个库 astoilkov/main-thread-scheduling,可用于跨浏览器的 JavaScript 任务调度。

2024 年 3 月 12 日,谷歌将推出一项新的核心网页指标,交互到下一次绘制 (INP)。INP 将取代首次输入延迟 (FID),这将改变谷歌评估网站性能的方式,最终影响你的网站在搜索引擎结果中的排名。

简而言之:你需要从今天开始优化 INP,以免在 3 月 12 日之后对你的网站产生负面影响。

为什么要更改?

FID 核心网页指标 设计用来衡量网页对用户首次操作的响应速度。一个好的 FID 分数是在 100ms 或更少时间内实现的。

然而,“Chrome 的使用数据显示用户在页面加载后花费了 90% 的时间,” 因此 FID 并未捕捉到完整的用户体验。因此,INP 被设计来衡量页面整体的 感知 响应能力,通过观察整个用户在页面上的旅程中的点击、轻触和按键操作 — 而不仅仅是第一次交互。

最终的 INP 值计算为观察到的在用户执行操作和接收视觉反馈之间的最长时间。用户互动的例子包括点击按钮将产品添加到购物车、点击可展开的手风琴或轻触折叠的导航菜单以及在输入字段中输入。INP 关注在特定操作执行后呈现视觉反馈所需的时间(即下一次绘制 —— 绘制是浏览器将像素添加到屏幕的过程),并排除互动的最终效果(如网络请求或 UI 更新)。

inp_add_to_cart_example

在开发者工具中调查 INP

让我们看看如何使用基于 Chromium 的浏览器(如 Chrome、Brave、Edge 和 Arc)来调查对 INP 指标有贡献的行为和事件。

选择一个接受以下用户互动之一的网页,INP 将进行测量(例如,滚动和移动指针不在测量范围内):

  • 使用鼠标点击
  • 在带有触摸屏的设备上轻触
  • 在物理或屏幕键盘上按键

我选择调查在 Sentry Docs 主页上搜索 “web vitals” 发生的情况。打开开发者工具面板,点击 “Performance” 标签。

inp_click_performance_tab

根据网站目标受众的不同,经常会很有帮助地限制 CPU 或网络速度,以分析在旧机器和/或较慢的互联网上的用户体验。如果你想要模拟较慢的 CPU 或网络,可以相应地配置选项。

inp_throttle_during_test

点击记录按钮,并在页面上进行一些互动。

inp_record_profile

停止记录,等待配置文件加载。你现在将看到大量数据,以带标签的彩色块形式出现在命名的轨道中。在分析对 INP 的贡献因素时,最重要的轨道是 “Interactions”(在页面上执行的任何用户互动)和 “Main”(浏览器的主线程)。

inp_lanes_annotated

为了给出一些背景,主线程是“浏览器处理用户事件和绘制操作的地方。” 默认情况下,浏览器使用主线程执行页面上的所有 JavaScript,布局页面,重新计算任何变化,并分配及释放内存(垃圾回收)。这意味着长时间运行的 JavaScript 函数可以阻塞主线程,导致页面无响应和糟糕的用户体验。这正是谷歌鼓励开发者解决问题的地方,通过引入 INP 指标。

当你检查你记录的性能轮廓时,你可能会看到主线程上的阻塞以红色突出显示;这表明一个长时间运行的任务。悬停在一个任务上时,你可以看到任务运行所需的时间,在该任务块下面,你将找到组成该任务的所有单独事件和函数调用。通过在鼠标或触控板上滚动来放大/缩小,使用窗口右侧的滚动条上下滚动堆栈。

inp_long_task_on_hover

车道下方的摘要标签页显示每个任务中分配给不同过程的时间量。这将因任务而异,但通常你会观察到“脚本编写”(即 JavaScript 过程)和“加载”所需时间最长。

inp_aggregate_summary

现在,让我们来对照主线程活动和交互轨迹。在这个例子中,我在 Sentry 文档首页的搜索输入框中输入了“web vitals”。在主线程的任务块下面,你会看到许多“事件:按键”块,这些是在我输入每个字母时捕捉到的。在交互轨迹中,有标记为“键盘”的块,表明我在输入。悬停在这些块上会告诉我们“长时间交互导致性能不佳”。

inp_keypresses_long_response

还要注意块两侧的胡子图案。这表明交互目前被主线程上的活动所阻塞,意味着页面可能看起来没有响应。当我输入时(CPU 节流),这种无响应是明显的。

点击键盘交互块可以让我们进一步检查这次交互。摘要显示这次交互有 45ms 的输入延迟,83.1ms 的处理时间,以及 84.638ms 的展示延迟。交互的总时间为 212.74 ms。

inp_keyboard_action_summary

==谷歌表示良好的 INP 分数应等于或小于 200ms,较差的分数大于 500ms,需要改进的分数在 200 到 500ms 之间。==根据这些标准,我们的分数需要提高。

要了解每个任务中哪些过程耗时最长,请选择一个任务块,然后单击下面的“自下而上”选项卡。这显示了哪些活动直接占用了最多的总时间。点击“总时间”列标题按时间升序或降序排序。

inp_bottom_up_annotated

展开每个事件以查看后续事件的完整列表以及它们各自的执行时间。将这个详细列表与你认为应该发生的事件进行比较,可以帮助你识别任何异常情况。

改善你的网站和应用的 INP

现在你已经熟悉如何通过将交互与主线程活动相互参照来调查阻塞过程,在开发中,你应该如何修复导致 INP 分数差的问题呢?通常情况下,这依赖于具体情况。但如果你在网页上发现了可能影响 INP 分数的意外长时间运行的任务,这里有一些问题供你自问:

  • 你是否提供了及时的视觉反馈?下一次绘制是否在 200 毫秒内发生?
  • 有没有什么在你不期望的时候运行?你能移除那个过程吗?
  • 你真的需要单独处理每次用户交互吗,或者你可以通过防抖来限制函数调用?
  • 你能否把产生的函数调用从主线程中提取出来,然后移到 web worker

还有一些更实验性的方法可以改善页面的感知响应速度,但要小心进行,因为它们可能不会在所有浏览器上得到支持。

navigator.scheduling.isInputPending()

仅支持 Chromium 浏览器,isInputPending() 允许你检查事件队列中是否有未处理的输入事件,表示用户正尝试与页面交互

当你有一系列任务要运行(比如每次按键时都调用 API),而你想定期将控制权返还给主线程以允许页面响应更多用户交互时,这可能会很有用。在撰写本文时,目前还没有任何计划将这个 API 在其他浏览器引擎中提供。

scheduler.yield

Chrome 团队的另一个实验性功能是 scheduler.yield,它扩展了调度程序 API 以使将控制权交还给主线程“更容易且更好”,而非以前使用的方法,如使用 setTimeout() 手动推迟代码执行

这两个新的 API 提供了一些很好的阅读机会,以理解浏览器中的 JavaScript 实际是如何工作的,但最终,如果没有所有浏览器的支持,这并不是你现在就急于采用的东西。

跨浏览器的 JavaScript 任务调度器

在为这篇文章进行研究时,我发现了 main-thread-scheduling,这是由 Antonio Stoilkov 开发的 JavaScript 任务调度器,专注于帮助你提升感知的页面性能,因此,提高你的 INP 分数。如果可用,它会使用 isInputPending(),但为所有浏览器提供调度功能。个人来说,我还没有用例去测试它,但乍一看,它目前正在维护,可能值得一试。

总结

通过引入新的 INP 核心 Web Vital 来替代 FID,开发人员被鼓励优先考虑最小化整个用户旅程中视觉反馈的延迟。这可以向用户保证一个页面正在响应他们的操作,这在理论上,应该减少摩擦和跳出率,改善整体的网页体验。

底线是什么?作为为 Web 构建的开发人员,即使我们并不总能完全控制获取数据和对前端 API 服务进行调用所需的时间,在为了获得良好的 INP 分数,我们需要让我们的页面_始终感觉快速_。