Q10 · React / Vue 优化

React 在开发过程中的性能优化策略?

ReactmemouseMemouseCallback

⚡ 速记答案(30 秒)

  • 使用 React.memo / PureComponent 避免重复渲染
  • useMemo / useCallback 缓存计算和回调,避免子组件不必要更新
  • 合理拆分组件,利用 key 保证列表 diff 稳定
  • 按需加载、懒加载路由和组件
  • 避免在 render 中创建新对象/函数,避免巨大的列表一次性渲染(用虚拟列表)
  • 使用生产构建(关掉 dev 校验),必要时开启 Concurrent / useTransition

📖 详细讲解

React 性能优化分层


1. 组件级优化


React.memo:避免 props 未变时重渲染

useMemo:缓存计算结果

useCallback:缓存回调函数

合理拆分:让状态变化只影响局部


2. 渲染优化


虚拟列表:react-window / react-virtualized

懒加载:React.lazy + Suspense

Key 稳定:避免用 index 做 key


3. 状态管理


减少全局状态:避免一改全动

状态下沉:状态放在需要的最近位置

选择性订阅:只订阅需要的部分


4. Concurrent 特性


useTransition:区分紧急/非紧急更新

useDeferredValue:延迟非关键渲染

💻 代码示例

React.memo + useCallback
import { memo, useCallback, useState } from 'react';

// 子组件使用 memo 包裹
const ExpensiveChild = memo(({ onClick }: { onClick: () => void }) => {
  console.log('ExpensiveChild 渲染');
  return <button onClick={onClick}>点击</button>;
});

function Parent() {
  const [count, setCount] = useState(0);
  const [other, setOther] = useState(0);

  // 使用 useCallback 避免每次创建新函数
  const handleClick = useCallback(() => {
    console.log('clicked');
  }, []); // 依赖为空,函数永不变化

  return (
    <div>
      <p>count: {count}</p>
      <button onClick={() => setCount(c => c + 1)}>增加</button>
      
      {/* other 变化不会导致 ExpensiveChild 重渲染 */}
      <button onClick={() => setOther(o => o + 1)}>其他</button>
      
      <ExpensiveChild onClick={handleClick} />
    </div>
  );
}
💡
面试技巧:回答性能问题时,先说指标和标准,再讲优化手段,最后结合实际项目经验。