fid精确测量用户首次触发有效交互(如click、keydown)后,浏览器主线程从排队等待到开始执行回调的延迟,即事件触发时刻与主线程实际处理时刻的差值,本质是“排队时间”而非执行耗时或渲染完成时间。

FID 不是用来评估“用户交互的实时响应能力与执行时机”的综合指标,它只精确衡量一件事:用户首次触发有效交互(如 click、keydown)后,浏览器主线程从排队等待到真正开始执行回调之间的延迟。这个值越小,说明主线程越空闲、越“跟手”;它不反映执行耗时,也不覆盖后续交互。
明确 FID 实际测量的对象
FID 测的是事件触发时刻(event.timeStamp)和主线程开始处理该事件时刻(近似用 performance.now() 获取)的差值。它本质是“排队时间”,不是“反应时间”或“渲染完成时间”。例如:
- 用户点击按钮瞬间,主线程正解析一个 2MB 的 JS 包 → FID 可能达 400ms
- 回调函数本身只做 console.log,执行仅 1ms → 这 1ms 不计入 FID
- 后续点击同样按钮,即使更卡,FID 也不再记录 —— 它只认第一次
哪些操作算有效交互?哪些不算?
FID 有严格的行为边界,不是所有用户动作都会被计入:
- ✅ 认可的事件类型:click、keydown、mousedown、touchstart
- ✅ 前提是目标元素绑定了对应事件监听器(空 div 点击无 handler → 不计)
- ❌ 滚动、缩放、hover、focus、input 输入(除非绑定 keydown)、页面后台时的点击,全部排除
- ❌ 页面未加载完成前的点击(如 script 还在下载中),通常无法捕获,也不属于 FID 范畴
如何获取真实可用的 FID 数据
不能依赖 performance.getEntriesByName('first-input'),它的 duration 字段是回调执行耗时,不是排队延迟。必须手动监听并计算:
- 尽早注册监听(建议放在 内联脚本中)
- 对每个匹配事件,立即用 performance.now() - event.timeStamp 得出近似排队延迟
- 捕获首个有效值后,立刻移除所有监听器(避免重复或干扰)
- 过滤掉 document.hidden === true 的情况,防止标签页切换误报
- 建议加一层校验:若差值 500ms,可丢弃(防系统时钟异常或误触)
FID 的实际价值与局限
FID 是现场(field)指标,只在真实用户会话中产生,Lighthouse 等工具无法模拟。它和用户是否“觉得一碰就动”高度相关:
- FID ≤ 100ms:体验顺滑,主流推荐阈值
- 100ms
- FID > 300ms:明显延迟,需优先优化主线程阻塞
但它不反映深度使用阶段的性能——用户点第二次、第三次卡不卡,FID 完全不管。这也是为什么 Google 已于 2024 年 9 月正式用 INP(Interaction to Next Paint)取代 FID,转向对“每一次”交互的端到端评估。










