Core/Dash 维度: 输入类型 (INP)

识别是哪个用户操作导致了你最差的 INP,并优先修复正确的交互处理程序。

免费试用

Trusted by market leaders · Client results

vpnperionharvardcompareebaynestleadevintamy work featured on web.devdpg mediahappyhorizonsnvkpnfotocasaloopearplugsaleteiaerasmusmcmarktplaatsnina carewhowhatwearmonarchsaturnworkiva

维度:输入类型 INP (inpit)

输入类型 (INP) 维度记录了在用户访问页面期间触发单次最差交互的 DOM 事件类型。该值是来自浏览器 Event Timing API 的原始事件名称:clickkeydownpointerdownpointerupkeypress 以及其他少数几个事件。

INP 是一种最坏情况指标。它不会对交互进行平均。它会找出从输入到下一次绘制耗时最长的那次交互,并报告其持续时间。输入类型维度会告诉你用户在那个确切时刻正在做什么。这就是“知道 INP 是 450 毫秒”与“知道 INP 是 450 毫秒是因为用户在你的搜索框中输入了内容”之间的区别。

Event Timing API 将相关事件组合成单个逻辑交互。在触摸屏上点击会触发 pointerdownpointerupclick,它们属于同一个组。该组中耗时最长的单个事件处理程序将决定交互延迟。CoreDash 会记录耗时最长的处理程序的事件类型,也就是导致交互变慢的那个事件。

为什么输入类型对 INP 至关重要

每种输入类型都映射到 JavaScript 代码库的不同部分。如果你在 INP 较差的页面上看到 keydown 是主要的输入类型,你立刻就能知道问题出在按键处理程序中:自动完成、输入即搜索或者每次按键时运行的表单验证。如果你看到 click,问题就出在按钮和链接处理程序中:导航逻辑、状态更新、模态框打开、同步触发的分析调用。

如果没有这个维度,排查 INP 就需要从性能分析会话 (profiling sessions)、重现步骤以及猜测第 75 百分位数的用户当时尝试进行哪种交互开始。有了输入类型维度,你可以直接跳到相关的处理程序。节省的时间是实实在在的。

输入类型还能揭示平台差异。一个包含大量高级用户键盘导航的网站,会显示高比例的 keydown 事件导致糟糕的 INP。一个主要在移动端使用的产品则会显示 pointerdown 占主导地位。同一个页面,相同的 INP 分数,根据你的实际用户是谁,会将相同的修复应用到不同的处理程序中。

输入类型

click 和 pointerdown

这些是 CoreDash 数据中最常见的输入类型,占最差 INP 事件的约 75%。在桌面端,click 代表鼠标按键释放。在移动端,一次轻触会触发完整的链条:当手指触摸屏幕时首先触发 pointerdown,然后手指抬起时触发 pointerup,最后触发 click。CoreDash 会记录该链条中具有最长处理程序的那个事件。

Click 处理程序是繁重同步 JavaScript 工作的核心发生地。在导航项上单次点击就可以在同一个任务中触发状态管理更新、DOM 变更、分析事件以及重新渲染。click 处理程序中每增加一毫秒的同步工作,INP 就会增加一毫秒。

修复慢 click 处理程序的方法是任务分解。使用 scheduler.yield() 将处理程序拆分为较小的任务,并让浏览器在这些任务之间进行渲染。将分析调用等非关键工作移入零延迟的 setTimeout 中,或者将它们完全推迟到 requestIdleCallback。浏览器只需要在下一次绘制之前完成会影响视觉响应的工作。其他所有工作都可以等待。

keydown

在 CoreDash 数据中,键盘输入约占最差 INP 事件的 15%,但它会产生一些最令人震惊的糟糕分数。原因在于频率:在搜索框中键入内容的用户在每次按键时都会触发 keydown。如果你的处理程序耗时 200 毫秒,那么用户在键入每个字符后都会体验到 200 毫秒的延迟。一个 10 个字符的搜索查询就会演变成 2 秒的累计阻塞时间。

常见的罪魁祸首是:在每次按键时触发同步 API 请求或运行昂贵的 DOM 差异比对的输入即搜索实现,以及在每次按键时重新检查整个表单的表单验证。这些模式在小规模下运行良好,但在真实用户环境下就会崩溃。

标准修复方法是防抖 (debouncing) 和任务分流 (offloading)。对你的搜索处理程序进行防抖处理,使其仅在用户暂停键入后触发,通常为 200 到 300 毫秒。对于更复杂的处理(例如在大型本地数据集中进行模糊搜索),请将计算移至 Web Worker,以便在每次 keydown 事件之后,main thread 仍可自由渲染下一帧。

pointerup

在 CoreDash 数据中,Pointer up 事件约占最差 INP 情况的 8%。pointerup 在触摸或点击序列结束时触发,处于 pointerdown 之后。某些框架和 UI 库会将其主要的 “click” 行为绑定到 pointerup 而不是 click,这会将处理程序移到交互生命周期中更早的阶段。

pointerup 成为主要的输入类型时,排查方法与 click 处理程序相同:找出处理程序中运行了什么 JavaScript,并将必须阻塞下一次绘制的工作与可以延迟的工作分离开来。它与 click 的区别通常是框架级别的决定,而不是应用级别的,因此修复可能涉及调整组件库处理交互绑定的方式。

排查工作流

  1. 在 CoreDash 中按输入类型进行过滤:打开有问题的 URL 的 INP 细分,检查哪种输入类型在最差交互中占主导地位。如果某一种类型占了糟糕 INP 事件的一半以上,就从那里开始。这种分布会告诉你应该把性能分析时间花在什么地方。
  2. 用正确的交互重现问题:打开 Chrome DevTools,启用 Performance 分析,并执行 CoreDash 中显示的确切交互类型。以 keydown 为主的页面应该通过键入内容来测试。以 click 为主的页面应该通过鼠标点击用户交互的元素来测试。记录跟踪 (trace),并识别在输入事件后立即触发的 main thread 中的 long task。
  3. 应用针对特定类型的修复并进行验证:对于 keydown 问题,添加防抖并重新进行性能分析。对于 click 问题,在处理程序的逻辑断点处添加 scheduler.yield() 调用。部署到测试环境,使用带有交互脚本的 WebPageTest with interaction scripting 或 Chrome DevTools Performance 面板,确认任务持续时间下降后再发布。

工程经验法则

  • keydown 占糟糕 INP 的主导地位:对所有搜索和自动完成处理程序添加防抖。200 毫秒的延迟是标准的起点。如果即使在此延迟下计算依然昂贵,请使用 Web Worker 将其移出 main thread。
  • click 或 pointerdown 占主导地位:在浏览器能够进行绘制之前,你的处理程序执行了太多同步工作。审计有问题的 URL 上的每个 click 处理程序。移除同步的分析调用。在步骤之间使用 scheduler.yield() 来分解多步逻辑。
  • pointerup 占主导地位:检查你的框架是否将交互逻辑绑定到 pointerup 而不是 click。修复方法通常与 click 处理程序相同,但代码库中的入口点不同。
  • 混合分布且无明显的占主导类型:问题不在于单一的交互类型。对所有类型中最慢的三种具体交互进行分析,并按影响程度顺序进行解决。不要进行抽象地优化。

输入类型是一个路由信号。它不会告诉你什么东西慢,而是告诉你该看哪里。一旦你知道当 INP 崩溃时,你的用户是在点击、键入还是轻触,后续的每一个排查步骤都会变得更快、更具针对性。