报错是这么冒出来的。数据看板每三秒刷新一次,表格宽度变化触发 ResizeObserver,回调里重算全部 200 行的高度。移动端点击筛选按钮后要等 480ms 才有反馈,INP 长期在红区。

中间走过弯路,把「刷新频率固定三秒,和用户操作叠加在一起」当成主因,改完现象没变。

这类报错背后常见的原因有几处,逐个排除就行。回调里同步读写布局属性,触发了强制重排。也可能是观察器挂在每个单元格上,回调被调用上百次。

还有一种情况,没有用 requestAnimationFrame 合并同一帧的更新。

定位长任务来源

performance.getEntriesByType('longtask').map(e => e.duration)

只观察容器而不是每个单元格

new ResizeObserver(onResize).observe(tableWrap)

接着把重算合并到下一帧

requestAnimationFrame(() => computeRows())

移动端复测 INP

https://pagespeed.web.dev/

怎么算真的好了,看的是同一批现象。点击到反馈的延迟降到 150ms 以内,INP 从红区回到良好,长任务数量明显减少。

ResizeObserver 回调本身不慢,慢的是回调里同步读布局再写样式的组合,拆开就能省下大半时间。监控比日志更早给出信号,事后回看经常能提前半小时发现异常。

作者 9823189