性能定位与分析
性能定位与分析 · 阅读后完成下方实验与检查题,再用「标记完成」记录进度。
学习目标
读完你能走完一次完整的性能定位闭环:复现卡顿 → 用 Profiler / DevTools 记录证据 → 定位瓶颈类型 → 修改 → 用同一把尺子对比数据;并建立「渲染次数不等于问题」的判断框架。
问题场景
「课程库页面有点卡」——凭感觉开优化:先给所有组件包 memo,没用;又把列表改成在 Effect 里直接操作 DOM,更卡了;最后上分页,问题没了,但需求不答应。三轮无效修改的原因相同:没有先测量。性能优化的每一步都应该是「证据 → 假设 → 修改 → 再测量」,而不是「听说 → 就改」。
核心解释
定位闭环五步:
**一、定量化复现。**把「有点卡」变成「输入关键词后到列表更新平均慢约 120ms」。用 React 的 Profiler 组件录制交互期间的渲染耗时:
<Profiler id="course-list" onRender={(id, phase, duration) => {
if (duration > 16) console.log(id, phase, duration.toFixed(1) + "ms");
}} />
**二、归类瓶颈。**常见三类对号入座:单次渲染太长(重计算,查昂贵计算)、渲染太频繁(该缓存的没缓存或状态放太低)、非渲染开销(强制同步布局、DOM 节点过多,用 Chrome Performance 面板看 Layout / Recalculate Style 段)。归类错误是无效修改的第一原因——把「布局抖动」当「渲染慢」去加 memo,当然没用。交互到下一帧的延迟也可以直接量:
const t0 = performance.now();
setKeyword(value);
requestAnimationFrame(() => {
console.log("交互到下一帧:", (performance.now() - t0).toFixed(1), "ms");
});
**三、修改一处,一次一处。**同时改三处,就永远不知道哪处起效。
**四、同一把尺子再测量。**同样的操作、同样的数据量,对比 onRender 的 duration 或 Performance 录制的总时长;改善要能用数字表达,「感觉快了」不算数。
**五、记录归档。**瓶颈是什么、改了什么、数据变化多少,三个字段写进提交说明——下次同类问题直接翻档案。
关键纠偏:渲染次数不是罪证。一秒渲染 60 次但每次 0.2ms 的组件不需要优化;一年渲染一次但单次 900ms 的组件才需要。看的永远是「时长 × 频率」对交互的影响。
示例拆解
实验区内置一个真实的性能缺陷并配了「测量台」:
- 列表排序计算带「瓶颈在位」开关(开启时排序 ×40),「已修复」开关控制是否用 useMemo 缓存;
- 每次计算的真实耗时被记入测量记录,页面上保留最近五条;
- 定位流程:开「瓶颈在位」、关「已修复」→ 输入关键词与点「无关刷新」,量出单次耗时;
- 修复与复测:勾上「已修复」(缓存生效)→ 同样操作再测,前后数字直接对比;
- 验证:完整走一遍「测 → 定位 → 修 → 再测」,把前后数字记进你的笔记。
动手任务
打开本课实验区:
- 在未修复状态量化卡顿:记下单次渲染耗时,并点「无关刷新」确认每次渲染都在重算。
- 勾选「已修复」再测一遍,填出「修改前 / 修改后」对比表,并解释缓存依赖是哪几项。
- 把这次定位写成三行档案(瓶颈 / 修改 / 数据变化),存进你的笔记。
常见错误
- 没测量就优化:凭感觉包 memo、拆组件,大概率白改;先数据后动作。
- 把渲染次数当问题:渲染多但便宜不是问题,渲染少但昂贵才是;看时长 × 频率。
- 一次改多处:无法归因,也无法验证哪处有效;单变量修改。
- 在开发构建下测性能:开发模式额外开销大,结论要在生产构建下复核。
检查与复盘
自查清单:
- 每次优化都走完「测量 → 定位 → 修改 → 再测量」闭环
- 能按三类瓶颈给自己的卡顿场景对号入座
- 优化结论用数字表达,并已归档
参考资料
- React 官方文档:Profiler —— 编程式测量渲染时长
- Chrome DevTools:性能面板 —— 渲染之外开销的定位
- React 官方文档:渲染与提交 —— 理解测量的对象是什么
读完这一课了?
标记完成后,工作台会安排接下来的学习。