对于面试和实际项目来说,React 优化一般分为 渲染优化、打包优化、网络优化、列表优化、状态管理优化 五大类。
结合你做过性能平台、ECharts、后台管理系统的经验,下面这些是最常见且最实用的优化方案。
一、减少不必要的渲染
1. React.memo
适用于:
-
子组件依赖 props
-
父组件频繁更新
const Child = React.memo((props) => {
;
return
});
避免:
Parent重新渲染
↓
Child跟着重新渲染
2. useMemo
缓存计算结果。
错误
const list = users.filter(item => item.age > 18);
每次 render 都执行。
优化
const list = useMemo(() => {
return users.filter(item => item.age > 18);
}, [users]);
3. useCallback
缓存函数引用。
错误
<Button onClick={() => handleClick()} />
每次 render 创建新函数。
优化
const handleClick = useCallback(() => {
console.log("click");
}, []);
二、大数据列表优化
这是后台系统最容易遇到的问题。
1. 虚拟列表
例如:
10000条数据
不要一次渲染。
使用:
-
<FixedSizeList
height={500}
itemCount={10000}
itemSize={35}{Row}
实际只渲染可视区域。
2. 分页加载
后台管理系统推荐:
每页20条
每页50条
不要直接:
一次加载10000条
三、路由懒加载
后台项目经常几十个页面。
普通写法
import User from './User';
全部打进首屏。
优化
const User = React.lazy(() =>
import('./User')
);
<Suspense fallback={<Loading />}>
<User />
</Suspense>
实现:
按需加载
四、Webpack/Vite打包优化
1. Tree Shaking
错误:
import * as lodash from "lodash";
优化:
import debounce from "lodash/debounce";
2. 代码分包
例如:
react
antd
echarts
拆分独立 chunk。
Vite:
manualChunks:{
react:['react','react-dom'],
antd:['antd'],
echarts:['echarts']
}
3. gzip压缩
服务器开启:
gzip
brotli
包体积通常能减少:
70%左右
五、图片优化
懒加载
<img
loading="lazy"
src={url}
/>
WebP
原图:
500KB
WebP:
100KB
CDN
静态资源走:
-
OSS
-
COS
-
CDN
减少服务器压力。
六、状态管理优化
Redux Selector缓存
错误:
const users = store.users.filter(...)
每次 render 计算。
优化:
import { createSelector } from "reselect";
const getUsers = createSelector(
[state => state.users],
users => users.filter(...)
);
七、ECharts优化(你项目经常会遇到)
你做性能平台应该碰到过。
数据抽样
sampling: 'lttb'
progressive
progressive: 5000
dataZoom
dataZoom:[]
避免一次渲染几十万点。
八、接口优化
防抖
搜索框:
debounce(fn,500)
节流
滚动:
throttle(fn,300)
请求缓存
可以用:
减少重复请求。
九、React 面试高频优化题
如果面试官问:
React 项目做过哪些性能优化?
可以按这个顺序回答:
1. React.memo减少组件重复渲染
2. useMemo缓存计算结果
3. useCallback缓存函数
4. React.lazy实现路由懒加载
5. react-window实现虚拟列表
6. ECharts数据抽样和按需渲染
7. webpack分包与gzip压缩
8. 图片懒加载和CDN
9. debounce/throttle减少无效请求
10. Redux Selector缓存计算结果
、