一、前端性能问题本质是什么?(先立认知)
性能问题 ≈ 不必要的渲染 + 不必要的计算 + 不必要的资源消耗
核心目标只有两个:
- ❌ 找出 谁在频繁变化
- ❌ 找出 为什么它在变化
二、如何定位「组件为什么会变化 / 重渲染」⭐⭐
1️⃣ React DevTools(必会)
开启方式
- React DevTools → ⚙️ → 勾选 Highlight updates
- 组件更新时会闪烁
👉 快速看到 哪些组件在重渲染
2️⃣ React Profiler(核心工具)
用法
- DevTools → Profiler
- 点击 Record
- 操作页面
- Stop
你能看到:
- 哪个组件渲染最慢
- 渲染耗时
- 重渲染次数
- 父子组件关系
3️⃣ why-did-you-render(神器 ⭐)
作用
👉 精准告诉你:组件为什么重渲染
Component.whyDidYouRender = true;
输出:
- props 变化
- 引用变化
- state 变化
4️⃣ 手动定位(简单但有效)
console.log('render');
useEffect(() => {
console.log('props changed');
}, [props]);
👉 初期排查非常有用
三、常见导致组件频繁变化的原因(高频)
❌ 1. 父组件 state 变化
setState → 父 render → 子 render
❌ 2. 引用类型每次都变
<Comp obj={{ a: 1 }} />
❌ 3. 函数作为 props
onClick={() => {}}
❌ 4. key 使用不当
key={index}
❌ 5. Context 滥用
👉 Context 变化 = 所有消费组件重渲染
四、如何定位「性能问题」⭐⭐⭐
1️⃣ Chrome Performance 面板(必会)
能看到:
- JS 执行时间
- Layout / Paint
- 强制同步布局
- Long Task(>50ms)
2️⃣ Performance.mark / measure
performance.mark('start');
// logic
performance.mark('end');
performance.measure('test', 'start', 'end');
3️⃣ Web Vitals(线上必用)
指标:
- LCP
- FID
- CLS
web-vitals
4️⃣ 内存泄漏排查
常见问题
- 定时器未清理
- 事件未解绑
- 闭包引用
工具
- Chrome Memory → Heap Snapshot
五、如何“解决”组件变化和性能问题(对应方案)
1️⃣ 控制重渲染(React)
| 问题 | 解决 |
|---|---|
| props 引用变化 | useMemo |
| 函数变化 | useCallback |
| 无关更新 | React.memo |
| 状态过大 | 状态下沉 |
| Context 过大 | Context 拆分 |
2️⃣ 计算性能优化
- 防抖 / 节流
- Web Worker
- 虚拟列表
3️⃣ 渲染性能优化
- 懒加载
- 骨架屏
- IntersectionObserver
六、Vue 中如何定位(补充,面试加分)
- Vue DevTools
- performance tracing
- watch / computed 依赖追踪
- key / v-if / v-show 排查
七、真实项目排查流程(非常重要)
标准流程(可直接说你做过)
发现卡顿
→ React Profiler 找重渲染组件
→ why-did-you-render 查原因
→ Chrome Performance 查耗时
→ 对症 useMemo / 拆分状态
八、30 秒面试标准回答(直接背)
我通常通过 React DevTools 的 Profiler 定位重渲染组件,
再使用 why-did-you-render 分析 props 或 state 的变化原因;
对性能瓶颈则借助 Chrome Performance 分析 JS 和渲染耗时,
最终通过 memo、useCallback、状态拆分等方式优化。
九、一句话终极总结
性能问题不是“慢”,而是“不该做的事做太多”。