主题
React 性能优化
React 应用中的布局抖动和掉帧如何排查?
掉帧可能发生在 React 提交之后的样式、布局、绘制和合成阶段,需要把框架和浏览器时间线一起看。
面试官想考什么
- React render 慢和浏览器 layout 慢如何区分? 考察完整链路。
- 什么是 layout thrashing? 考察浏览器渲染基础。
- 动画为什么会掉帧? 考察属性和合成层。
- 如何用工具定位? 考察 Performance 使用。
一句话回答
text
用 Performance 时间线区分 React、样式计算、布局、绘制和合成成本,批量读写 DOM,优先使用 transform/opacity 动画,并减少会触发布局的大范围更新。面试回答详解
1. 渲染链路
text
React render/commit -> style calculation -> layout -> paint -> compositeReact 只负责更新宿主节点,浏览器仍要计算样式和布局。DOM 大、样式复杂、同步读写交错或频繁测量都会拖慢帧率。
2. Layout thrashing
在写入样式后立即读取 offsetHeight、getBoundingClientRect 等布局信息,可能迫使浏览器同步刷新布局。应批量读取,再批量写入,或使用 ResizeObserver/批处理。
3. 动画策略
优先动画 transform 和 opacity;宽高、top/left、阴影和复杂滤镜可能触发布局或绘制。合成层也不是免费,过多层会增加内存。
4. React 侧协作
缩小更新范围,避免每帧通过 state 驱动大树;连续动画可使用 CSS、Web Animations 或直接更新受控节点,但要保证清理和可访问性。
可直接背诵的 30 秒回答
text
我会用 Performance 时间线确认掉帧发生在 React render/commit、样式计算、layout、paint 还是 composite。代码上避免读写 DOM 交错造成强制布局,批量测量和更新;动画优先 transform/opacity,减少每帧触发大范围 React state 更新。优化后看帧率、Long Task、布局耗时和低端设备体验。扩展知识
帧性能模型
text
输入 -> JS -> React -> style/layout -> paint/composite -> 下一帧面试官追问链
追问一:transform 一定比 top/left 快吗?
- 考察点:是否避免绝对化结论。
- 回答方向:通常更容易走合成路径,但具体仍取决于元素、绘制和合成成本,要用 Performance 验证。
追问二:为什么加 will-change 后更慢?
- 考察点:是否理解合成层成本。
- 回答方向:过多层会增加内存、合成和管理成本,只对确实即将变化的元素短期使用。
追问三:React state 驱动动画可以吗?
- 考察点:是否能按频率选工具。
- 回答方向:低频状态可以;高频每帧动画通常交给 CSS/Web Animations 或直接 DOM 更新,避免整棵 React 树参与。