本文介绍 INP,以及如何借助 INP Scanner Milten 调查交互延迟。INP 于 2024 年 3 月取代 FID,成为 Core Web Vitals 指标。实验室测试只覆盖实际执行的操作,不能代表所有访客的体验。
什么是 Interaction to Next Paint(INP)?
INP 评估一次访问中点击、触屏轻点和键盘输入的响应情况。交互延迟包括输入处理前的等待、事件处理程序执行,以及下一次绘制前的等待。FID 只测量首次输入延迟,INP 则考虑整个访问期间符合条件的交互。它不测量随后异步网络请求完成所需的全部时间。
INP的主要特点:
- 汇总方式: INP 不是平均值。通常反映最慢的交互;当一次访问中交互很多时,会排除部分异常值。
- 阈值: 不超过 200 毫秒为良好;超过 200 毫秒且不超过 500 毫秒为需要改进;超过 500 毫秒为较差。真实访问应按移动端和桌面端分别评估第 75 百分位数。
- 包含的操作: 点击、触屏轻点和键盘输入。滚动和悬停本身不属于 INP 交互。
为什么 INP 对您很重要?
1. 用户体验(UX)
视觉反馈迟缓会让按钮看起来没有反应,可能导致重复点击。请测量具体交互及其结果。页面加载统计不能被当作 INP 对您网站跳出率影响的实测证据。
2. SEO 和搜索排名
INP 属于 Google 排名系统使用的 Core Web Vitals。良好的分数不保证更高排名,较差的分数也不能证明存在固定的排名惩罚。应结合内容相关性和其他页面体验因素评估响应性。
3. 速度作为竞争优势
及时的视觉反馈能让用户知道操作已被接收。请比较受众真正需要的任务:同样的延迟在不同任务中可能产生不同影响。
如何使用 Milten 的 INP Scanner
INP Scanner 帮助您在受控浏览器测试中调查响应情况。推广结论之前,请确认实际执行了哪些操作,以及报告的限制。
1. 确认测试过的交互
选择具有代表性的流程,并确认测试实际执行的操作:
- 点击按钮和链接。
- 在相关输入框中使用键盘。
- 为到达元素而滚动页面;滚动本身不是 INP 交互。
受控测试是可复现的场景,不是在所有访客设备上的测量。请记录浏览器、设备配置和实际测试条件。重要但未覆盖的流程应另外手动测试。
2. 理解时间数据
INP 测量使用 Event Timing 数据。PerformanceObserver 可以观察受支持的 event 条目,并不存在用于此目的的通用 render 条目。web-vitals 等库负责交互分组和 INP 计算。
- 区分输入等待、事件处理和呈现延迟。
- 调查主线程上执行较久的 JavaScript 任务。
- 将动画流畅度作为相关但不同的问题另行检查。
3. 调查报告中的问题
以报告中实际存在的证据为依据:
- 找到记录的交互及其目标元素。
- 调查缓慢的操作。例如,耗时 600 毫秒的“购买”按钮只是说明性案例,不是客户实测数据。
- 在浏览器性能记录中验证可能的原因,并测试范围有限的代码修改。
自动测试的边界
- 查看服务当前的使用条件和报告字段。
- 浏览器测试本身不代表测试过访客的实体设备。
- 未执行的操作和缺失数据仍属未验证;条件允许时,应补充真实访问数据。
导致交互缓慢的常见原因
1. 长事件处理程序
说明性示例:函数和数据需要在应用中定义。
button.addEventListener('click', () => {
// Synchronous processing of 10,000 data rows
const result = heavyCalculation(data)
updateUI(result)
})
问题:同步执行的 heavyCalculation 占用主线程,可能延迟下一次绘制。 解决方法:减少或拆分工作,将合适的计算移到 Web Worker。单次 setTimeout 只是把同一项繁重任务安排到稍后,并不会将其移出主线程。
2. 渲染阻塞 CSS/JS
示例:
<link rel="stylesheet" href="large-styles.css" />
<script src="analytics.js" defer></script>
问题:阻塞渲染的样式表和耗时的脚本执行可能延迟显示或输入处理。defer 改变执行时机,但不会消除执行成本。示例样式表适用于屏幕;仅使用 media="print" 会使这些样式不应用于屏幕。 可以考虑:
- 只内联确实关键的 CSS,并测量取舍。
- 检查动态类名和界面状态后,再删除未使用样式;PurgeCSS 需要正确配置。
- 延后非关键脚本,并降低执行成本。
3. 慢速动画
示例:
@keyframes fade {
from {
opacity: 0;
transform: translateX(-100px);
}
to {
opacity: 1;
transform: translateX(0);
}
}
问题:opacity 和 transform 动画通常较高效,但同时为大量元素设置动画仍可能卡顿。 可以考虑:
- 简化动画,减少同时运动的元素。
- 仅在需要时、接近变化发生前使用
will-change: transform。它是一种提示,并不保证 GPU 加速;过度使用会消耗资源。请测量结果。
4. 反复强制计算布局(layout thrashing)
示例:
for (let i = 0; i < 100; i++) {
element.style.height = `${i}px`
console.log(element.offsetHeight) // Forces layout recalculation
}
问题:交替写入样式和读取 offsetHeight 等几何属性,可能导致反复计算布局。布局计算与绘制是不同的步骤。 解决方法:
- 尽可能先集中读取几何信息,再集中写入。
- 在合适时使用
requestAnimationFrame安排视觉更新,但把同样的读写循环放进去并不能自动解决问题。
如何提高 INP:5 个实用技巧
1. 优化事件处理程序
- 拆分长任务,通过
setTimeout等适当机制,在各段之间将控制权交还浏览器。 queueMicrotask不会给浏览器提供绘制机会;连续的微任务可能继续阻塞页面。- 减少处理程序中的即时工作,并及时显示反馈。
2. 减少 JavaScript 包大小
- 删除未使用的库(例如,使用 Webpack Bundle Analyzer)。
- 应用代码分割来动态加载模块。
3. 使用去抖和节流
如果任务允许,可以使用 debounce 或 throttle 限制昂贵工作的频率。示例要求先定义或导入 debounce。输入框自身应立即响应;300 毫秒只是任务调度示例,并非 INP 目标。
const debouncedSearch = debounce((query) => {
fetchResults(query)
}, 300)
4. 优化渲染
- 减少不必要的 DOM 复杂度。
- 测量样式和布局成本,不要预先认定复杂选择器就是原因。
- 对屏幕外区域可考虑
content-visibility: auto,并检查布局、焦点和无障碍行为。
5. 在低端设备上进行测试
尽可能使用有代表性的低性能设备测试。浏览器开发者工具也能限制 CPU 和网络,例如将 CPU 减速 4 倍并使用受限移动连接。这是实验室条件示例,并不表示服务采用固定 3G 配置或测试实体设备。
验证修改结果
发布后,在可比较的条件下重复同一交互。既检查响应时间,也检查任务结果:更快的购物车仍须包含正确商品。
将 INP Scanner 和 Milten 的报告用于调查时:
- 记录测试过的操作和缺失的证据。
- 使用同一流程比较修改前后。
- 以真实访问数据评估真实访问;良好的实验室结果不能证明所有用户的 INP 都良好。
选择一个重要的缓慢交互,提出可能原因,再验证范围有限的修改。请区分通过、失败和未执行的检查。

