资讯文章 资讯 · NEWS
INP 取代 FID 之后:目录站上最容易拖慢响应的三个地方
2026-10-22 约 1,646 字 预计阅读 4 分钟 yiyunkj
I
去年我给一个目录站做例行体检,Core Web Vitals 报告里 FID 那一栏一直是绿的,我从来没为它操过心。到了 2024 年 3 月之后再看,同一个站、同样的代码,响应性指标直接变成了“需要改进”。代码一行没动,指标先变了。
这不是站变慢了,是尺子换了。这次切换对目录站尤其不友好,因为目录站恰好是那种“首屏很快、后面越点越卡”的页面结构。

图片来源:网络,版权归原作者所有,侵权请联系删除
FID 和 INP 量的根本不是一回事
FID 只测第一次交互的输入延迟,而且只测到事件开始处理为止。它有几个天然的盲区:只看第一次,不看后面;只算排队时间,不算处理时间和渲染时间。
INP 换了一套算法:统计一次访问中所有点击、触摸、按键,取其中最慢的那一次(访问量多时取接近最差的高分位),并且从交互发生一直算到浏览器画出下一帧。
差别就在这里。目录站的首屏点击通常很快就响应,FID 因此一直很好看。但用户在页面上点第三个筛选、第二次展开折叠分类、在搜索框里连着敲字的时候,主线程已经忙不过来了,而这部分恰恰是 FID 看不见的。
阈值和口径
| 指标 | 良好 | 需要改进 | 差 |
|---|---|---|---|
| INP(75 分位) | ≤ 200 毫秒 | 200 – 500 毫秒 | > 500 毫秒 |
评估按 75 分位算,移动和桌面分开。这意味着不是压平均值,而是要保证绝大多数访问都能落进 200 毫秒以内。目录站移动端占大头,实际上是被更严的那一档卡着。
还有个常被忽略的点:INP 只能测真实用户数据,来自 CrUX(Chrome 用户体验报告),是 28 天滚动窗口。Lighthouse 那种实验室跑分测不了 INP,它用 TBT(总阻塞时间)做近似替代。所以本地跑分全绿、线上报告却红,这种情况很常见。
目录站踩线的三类写法
一、一个页面几千个条目,每个都挂事件监听
典型场景是一个分类页不分页,直接铺几千个条目,每个条目卡片上都绑了点击统计、收藏、右键菜单。事件监听本身不贵,贵在两方面:绑定过程本身要跑一轮循环,触发之后事件要沿着 DOM 往上冒泡。
改法很直接:用事件委托,在容器上挂一个监听器,靠事件目标判断点了哪个条目;统计那部分不要在点击回调里同步发包,先写入队列延后处理。DOM 节点数也该控制,几千个节点的页面,样式重算在每次交互后都要跑一遍,这才是拖慢下一帧的元凶。
二、第三方脚本抢占主线程
统计代码、在线客服、广告位、联盟推广的 JS,每一家都说自己“异步加载不阻塞”。单看确实不阻塞,加起来就不一定了。它们会在主线程上注册自己的定时任务和监听,你的点击回调必须等它们跑完才能执行。
我的做法是按“能否延后到用户第一次交互之后”给第三方脚本分类。客服插件、广告位这类一律延后;只有统计脚本保留在加载阶段,而且用 requestIdleCallback 之类的机制发包。筛掉两个脚本就能降几十毫秒,这种案例我遇到过不止一次。
三、筛选、排序、搜索框没做节流
目录站最核心的交互就是筛选和搜索。如果用户在搜索框里敲十个字就触发十次过滤计算,每次计算都要遍历条目列表并重排 DOM,那么这一串交互里一定会产生一个难看的数值——而 INP 取的就是最难看的那个。
输入类交互必须做防抖或节流,一般 150 到 300 毫秒比较合适。过滤逻辑如果重,就把它拆成小块,让浏览器有机会在中间画一帧。排序结果多的时候用虚拟列表,只渲染视口内的那几十条。
改法清单
- 交互回调里只做必须同步完成的事,其余延后;
- 长任务拆块,主动让出主线程(setTimeout 0 或 scheduler.yield);
- 用事件委托替代成百上千个独立监听;
- 控制单页 DOM 规模,条目多的分类页该分页就分页;
- 第三方脚本按功能分级,非必要的延后加载;
- 输入类交互一律加防抖节流。
别为了 INP 把收录搭进去
这里有个需要自己权衡的地方。把条目改成点击后再渲染、把列表做成纯前端异步加载,INP 会好看很多,但搜索引擎能不能看到这些内容就成了新问题。我的处理方式是:首屏条目服务端直出,保证能被抓到;交互部分的优化只针对已经存在的 DOM,不做“先空后填”。
指标是为内容服务的。为了 200 毫秒把收录搞没了,这笔账不划算。