React 性能优化(全面版)
React 性能优化通常可以分为 渲染优化、状态管理优化、组件设计优化、打包优化、网络优化、列表优化、内存优化 七大类。
一、减少不必要的渲染(最重要)
1. React.memo
用于函数组件缓存。
javascript
const Child = React.memo((props) => {
console.log('Child Render');
return <div>{props.name}</div>;
});
未使用
ini
<Child name="Tom" />
父组件更新:
scss
setCount(count + 1)
Child也会重新渲染。
使用后
props没变:
scss
React.memo(Child)
不会重新渲染。
2. useMemo
缓存计算结果。
错误
ini
const list = bigData.filter(item => item.age > 20);
每次render都会执行。
优化
ini
const list = useMemo(() => {
return bigData.filter(item => item.age > 20);
}, [bigData]);
适用:
- 大数据计算
- 表格数据处理
- 树结构转换
- 图表数据处理
3. useCallback
缓存函数。
问题
scss
<Child onClick={() => handleClick()} />
每次都会生成新函数。
导致:
React.memo
失效。
优化
ini
const handleClick = useCallback(() => {
console.log('click');
}, []);
<Child onClick={handleClick} />
4. useRef代替State
错误
scss
const [timer,setTimer] = useState(null);
修改会触发渲染。
优化
ini
const timerRef = useRef(null);
timerRef.current = setTimeout(...)
不会触发render。
适合:
- 定时器
- DOM
- websocket实例
- 缓存变量
二、列表性能优化
大项目最容易卡顿的地方。
5. key不要乱写
错误
javascript
{
list.map((item,index)=>(
<Item key={index}/>
))
}
删除数据后:
csharp
[1,2,3,4]
变:
csharp
[2,3,4]
React会重新比较大量节点。
正确
ini
<Item key={item.id}/>
6. 虚拟列表
10000条数据:
c
list.map(...)
直接卡死。
使用:
- react-window
- react-virtualized
ini
<FixedSizeList
height={600}
itemCount={10000}
itemSize={50}
>
只渲染可视区域。
7. 分页加载
不推荐
一次加载10000条
推荐
每页20条
或者:
无限滚动
三、状态管理优化
8. 状态不要放太高
错误
css
App
├─A
├─B
├─C
所有状态放:
App
更新一次:
App重新render
所有子组件更新。
优化
状态下沉
css
A自己维护state
只更新A。
9. Context拆分
错误
ini
<UserContext.Provider
value={{
user,
theme,
language
}}
>
修改theme:
sql
user组件也更新
优化
UserContext
ThemeContext
LanguageContext
拆分Context。
10. Zustand替代复杂Context
大型项目推荐:
ini
const count = useStore(state => state.count)
按需订阅。
避免全局刷新。
四、组件设计优化
11. 组件拆分
错误
yaml
Page.jsx
2000行代码
任何状态变化:
整个页面render
优化
css
Page
├ Header
├ Search
├ Table
└ Footer
细粒度更新。
12. 懒加载组件
javascript
const ReportPage = React.lazy(() =>
import('./ReportPage')
);
xml
<Suspense fallback={<Loading/>}>
<ReportPage />
</Suspense>
13. 路由懒加载
ini
const Home = lazy(() => import('./Home'));
减少首屏体积。
14. 条件渲染优化
错误
javascript
{
show && <BigTable />
}
频繁卸载挂载。
优化
css
<div style={{
display: show ? 'block' : 'none'
}}>
<BigTable />
</div>
适用于频繁切换场景。
五、表格性能优化(企业项目重点)
你做过性能平台项目,这部分面试经常问。
15. 表格列配置缓存
错误
css
const columns = [ ...]
每次render重新创建。
优化
scss
const columns = useMemo(() => [ ...], []);
16. render函数缓存
错误
javascript
{
render: () => (
<Button>编辑</Button>
)
}
优化
ini
const renderAction = useCallback(
(record)=>{},
[]
);
17. 大表格虚拟滚动
Ant Design:
css
<Table
scroll={{
y:600
}}
virtual
/>
18. Echarts销毁优化
页面切换:
ini
chart.dispose();
避免内存泄漏。
六、请求性能优化
19. 防抖(debounce)
搜索框:
lodash.debounce
ini
const search = debounce(() => {
api();
},500);
20. 节流(throttle)
滚动事件:
lodash.throttle
ini
const scroll = throttle(()=>{
},300);
21. 请求缓存
erlang
react-query
现在叫:
scss
useQuery(...)
自动缓存。
22. 请求合并
错误
scss
getUser()
getRole()
getDept()
优化
scss
Promise.all([
getUser(),
getRole(),
getDept()
])
七、打包优化
23. Tree Shaking
错误
javascript
import _ from 'lodash';
优化
javascript
import debounce from 'lodash/debounce';
24. Code Splitting
scss
import()
动态加载。
25. Gzip/Brotli压缩
服务器开启:
csharp
gzip on;
brotli on;
26. CDN资源
arduino
react.min.js
走CDN。
27. 图片优化
使用
- WebP
- AVIF
懒加载
ini
<img
loading="lazy"
/>
八、React18优化
28. useTransition
降低优先级更新。
scss
const [isPending,startTransition]
= useTransition();
startTransition(()=>{
setList(data);
});
适合:
- 搜索
- 大列表
29. useDeferredValue
ini
const deferredKeyword =
useDeferredValue(keyword);
输入不卡顿。
九、内存泄漏优化
30. 清理事件
scss
useEffect(()=>{
window.addEventListener(...);
return ()=>{
window.removeEventListener(...);
};
},[]);
31. 清理定时器
scss
useEffect(()=>{
const timer = setInterval(...);
return ()=>{
clearInterval(timer);
};
},[]);
32. 取消请求
scss
const controller =
new AbortController();
fetch(url,{
signal:controller.signal
});
return ()=>{
controller.abort();
}
十、React项目面试必答性能优化方案
如果面试官问:
React项目做过哪些性能优化?
可以按这个顺序回答:
- React.memo减少子组件渲染
- useMemo缓存复杂计算
- useCallback缓存函数
- 状态下沉,避免全局刷新
- Context拆分或使用Zustand
- 表格列配置useMemo缓存
- 大数据列表使用虚拟滚动
- 搜索使用防抖
- 路由和组件懒加载
- Tree Shaking + Code Splitting
- React18 useTransition优化大列表
- 清理事件、定时器、防止内存泄漏
对于你目前做过的 云鉴性能平台(React + Ant Design + ECharts) ,最有价值、最容易写进简历的优化点是:
- 表格虚拟滚动(千级数据)
- columns/useMemo缓存
- 搜索条件防抖
- ECharts按需渲染与dispose销毁
- React.memo组件级缓存
- 路由懒加载
- Promise.all接口并发
- Zustand/Redux选择性订阅
- React Query缓存接口数据
- React18 useTransition优化搜索结果渲染