R51第 1 / 1 课时未开始内容版本 1.0.0 · 核验于 2026-10-26

性能定位与分析

性能定位与分析 · 阅读后完成下方实验与检查题,再用「标记完成」记录进度。

学习目标

读完你能走完一次完整的性能定位闭环:复现卡顿 → 用 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 缓存;
  • 每次计算的真实耗时被记入测量记录,页面上保留最近五条;
  • 定位流程:开「瓶颈在位」、关「已修复」→ 输入关键词与点「无关刷新」,量出单次耗时;
  • 修复与复测:勾上「已修复」(缓存生效)→ 同样操作再测,前后数字直接对比;
  • 验证:完整走一遍「测 → 定位 → 修 → 再测」,把前后数字记进你的笔记。

动手任务

打开本课实验区:

  1. 在未修复状态量化卡顿:记下单次渲染耗时,并点「无关刷新」确认每次渲染都在重算。
  2. 勾选「已修复」再测一遍,填出「修改前 / 修改后」对比表,并解释缓存依赖是哪几项。
  3. 把这次定位写成三行档案(瓶颈 / 修改 / 数据变化),存进你的笔记。

常见错误

  • 没测量就优化:凭感觉包 memo、拆组件,大概率白改;先数据后动作。
  • 把渲染次数当问题:渲染多但便宜不是问题,渲染少但昂贵才是;看时长 × 频率。
  • 一次改多处:无法归因,也无法验证哪处有效;单变量修改。
  • 在开发构建下测性能:开发模式额外开销大,结论要在生产构建下复核。

检查与复盘

自查清单:

  • 每次优化都走完「测量 → 定位 → 修改 → 再测量」闭环
  • 能按三类瓶颈给自己的卡顿场景对号入座
  • 优化结论用数字表达,并已归档

参考资料

动手实验
动手实验
预览
点击「运行」在隔离沙箱中预览
检查题共 1 题,提交后立即显示解析
答案由服务端判定;答错的题会自动进入复习计划。
Q1单选中等

用户反馈「输入时页面卡顿」。下列定位手段中,最合理的第一步是?

读完这一课了?

标记完成后,工作台会安排接下来的学习。

Command Palette

Search for a command to run...