一、前端性能问题本质是什么?(先立认知)
性能问题 ≈ 不必要的渲染 + 不必要的计算 + 不必要的资源消耗
核心目标只有两个:
-
❌ 找出 谁在频繁变化
-
❌ 找出 为什么它在变化
二、如何定位「组件为什么会变化 / 重渲染」⭐⭐
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、状态拆分等方式优化。
九、一句话终极总结
性能问题不是"慢",而是"不该做的事做太多"。