React 项目常用代码优化方法
一、减少不必要的重新渲染(最核心)
React 最大的性能问题就是无效重渲染。
- React.memo 缓存函数组件,让组件只有在 props 真正变化时才重新渲染。
export default React.memo(MyComponent);
- useMemo 缓存计算量大的值,避免每次渲染都重新计算。
const handleClick = useCallback(() => setCount(count + 1), [count]);
- useCallback 缓存函数引用,防止子组件因函数变化而重复渲染。
const handleClick = useCallback(() => setCount(count + 1), [count]);
- 避免使用内联对象 / 函数作为 props 每次渲染都会创建新引用,导致子组件重渲染。
// 不好
<Child style={{margin:0}} />
// 好
const style = useMemo(()=>({margin:0}),[])
二、列表渲染优化
- key 必须使用稳定唯一值不要用 index,否则 Diff 算法失效。
items.map(item => <div key={item.id} />)
- 列表使用虚拟列表(react-window /react-virtualized)**只渲染可视区域,大幅减少 DOM 数量。
三、状态与逻辑优化
- 合理拆分组件
状态变化只影响最小范围的组件。
- useState 懒初始化
避免每次渲染执行复杂计算。
const [state, setState] = useState(() => initState());
- useReducer 替代多 useState(复杂状态)
状态更集中、更清晰,减少多次更新。
四、事件与副作用优化
- 防抖 / 节流(防抖用得最多)
搜索框、窗口 resize、滚动等高频事件。
import { debounce } from 'lodash';
const handleSearch = useCallback(debounce(fn, 300), []);
- useEffect 清除副作用
定时器、订阅、事件监听必须清除,防止内存泄漏。
useEffect(() => {
const timer = setInterval();
return () => clearInterval(timer);
}, []);
五、打包构建优化
-
路由懒加载 React.lazy + Suspense
const Home = React.lazy(() => import('./Home')); -
大组件 / 第三方库按需加载
如 AntD、ECharts 等。
-
开启 Gzip 压缩
积减少 60%~80%。
-
图片压缩、WebP 格式
六、其他高级优化
- 避免使用 React.Fragment 短语法 <> 造成额外层级(极少场景)
- 使用不可变数据 Immer,保证状态可追踪、减少渲染错误
- 使用 useMemo 缓存 context value防止 provider 重新渲染所有 consumer
面试背诵版
你在面试时可以这样流利回答:
- 减少重渲染:使用
React.memo、useMemo、useCallback缓存组件、值和函数。 - 列表优化:使用正确
key,长列表使用虚拟滚动。 - 状态优化:合理拆分组件,懒初始化 state,复杂状态用 useReducer。
- 副作用优化:防抖节流,清除定时器和订阅,避免内存泄漏。
- 打包优化:路由懒加载,代码分割,Gzip 压缩。
- 其他:使用不可变数据 Immer,优化 Context 传递。
参考文章链接