react性能优化

React 性能优化全面指南

React 应用性能优化是一个系统工程,需要从多个层面进行优化。以下是一套完整的 React 性能优化策略,涵盖从基础到高级的各种技术:

一、组件级优化策略

1. 记忆化组件

  • React.memo :避免不必要的重新渲染

    jsx 复制代码
    const MemoizedComponent = React.memo(MyComponent, (prevProps, nextProps) => {
      return prevProps.id === nextProps.id;
    });

2. 状态精细化

  • 避免在根组件存储所有状态

  • 将状态下放到使用它的最小组件

    jsx 复制代码
    // 不好的做法:状态提升过高
    const App = () => {
      const [user, setUser] = useState({});
      return <Profile user={user} />;
    };
    
    // 好的做法:状态下沉
    const Profile = () => {
      const [user, setUser] = useState({});
      return <UserCard user={user} />;
    };

3. 引用类型优化

  • useCallback:缓存函数引用

    jsx 复制代码
    const handleClick = useCallback(() => {
      console.log('Clicked');
    }, []);
  • useMemo:缓存计算结果

    jsx 复制代码
    const expensiveValue = useMemo(() => {
      return computeExpensiveValue(a, b);
    }, [a, b]);

4. 避免内联对象

  • 内联对象会导致每次渲染都创建新引用

    jsx 复制代码
    // 不好的做法
    <MyComponent style={{ color: 'red' }} />
    
    // 好的做法
    const style = useMemo(() => ({ color: 'red' }), []);
    <MyComponent style={style} />

二、渲染优化策略

1. 虚拟化长列表

  • 使用 react-window 或 react-virtualized

    jsx 复制代码
    import { FixedSizeList as List } from 'react-window';
    
    const Row = ({ index, style }) => (
      <div style={style}>Row {index}</div>
    );
    
    const VirtualList = () => (
      <List height={600} itemCount={1000} itemSize={35} width={300}>
        {Row}
      </List>
    );

2. 延迟加载组件

  • React.lazy + Suspense

    jsx 复制代码
    const HeavyComponent = React.lazy(() => import('./HeavyComponent'));
    
    const App = () => (
      <Suspense fallback={<div>Loading...</div>}>
        <HeavyComponent />
      </Suspense>
    );

3. 分片渲染

  • 使用 setTimeout 或 requestIdleCallback 拆分渲染任务

    jsx 复制代码
    const renderChunk = (startIndex, endIndex) => {
      requestIdleCallback(() => {
        // 渲染部分内容
        for (let i = startIndex; i < endIndex; i++) {
          renderItem(data[i]);
        }
      });
    };

三、状态管理优化

1. 状态选择器优化

  • 在 Redux 中使用 reselect

    jsx 复制代码
    import { createSelector } from 'reselect';
    
    const selectItems = state => state.items;
    const selectFilter = state => state.filter;
    
    const selectFilteredItems = createSelector(
      [selectItems, selectFilter],
      (items, filter) => items.filter(item => item.includes(filter))
    );

2. Context 优化

  • 拆分 Context 避免不必要更新

    jsx 复制代码
    // 创建多个 Context
    const UserContext = createContext();
    const ThemeContext = createContext();
    
    // 使用 Context Selector
    import { useContextSelector } from 'use-context-selector';
    
    const UserName = () => {
      const name = useContextSelector(UserContext, v => v.name);
      return <div>{name}</div>;
    };

3. 状态更新批处理

  • React 18 自动批处理异步操作

  • 手动批处理(React 17 及以下)

    jsx 复制代码
    // React 17 需要手动批处理
    import { unstable_batchedUpdates } from 'react-dom';
    
    const clickHandler = () => {
      setTimeout(() => { // 模拟异步
        ReactDOM.unstable_batchedUpdates(() => { // 仅仅加了unstable_batchedUpdates
          // 这里的两个setState会合并执行一次。
          setNum(2); 
          setStr('c');
        });
      }, 1000);
    }

四、网络与加载优化

1. 资源预加载

  • 使用 preload 和 prefetch

    html 复制代码
    <link rel="preload" href="critical.css" as="style">
    <link rel="prefetch" href="optional.js" as="script">

2. 代码分割

  • 基于路由的代码分割

    jsx 复制代码
    const Home = lazy(() => import('./Home'));
    const About = lazy(() => import('./About'));
    
    const App = () => (
      <Routes>
        <Route path="/" element={<Suspense fallback="..."><Home /></Suspense>} />
        <Route path="/about" element={<Suspense fallback="..."><About /></Suspense>} />
      </Routes>
    );

3. 图片优化

  • 使用 next/image (Next.js)或 react-lazy-load-image

    jsx 复制代码
    import { LazyLoadImage } from 'react-lazy-load-image-component';
    
    <LazyLoadImage
      src="image.jpg"
      placeholderSrc="placeholder.jpg"
      effect="blur"
    />

六、性能监测与分析工具

1. React DevTools

  • 组件渲染时间分析
  • Highlight updates when components render

2. Chrome Performance 工具

  • 录制性能时间线
  • 分析 JavaScript 执行时间

3. React Profiler API

  • 编程式性能分析

    jsx 复制代码
    <Profiler id="MyApp" onRender={onRenderCallback}>
      <App />
    </Profiler>
    
    function onRenderCallback(
      id, // 组件ID
      phase, // "mount" 或 "update"
      actualDuration, // 本次渲染花费时间
      baseDuration, // 不使用memoization的估计时间
      startTime, // 开始时间
      commitTime, // 提交时间
      interactions // 本次更新相关的交互
    ) {
      // 记录或分析这些信息
    }

4. Lighthouse 审计

  • 全面的性能评分
  • 优化建议

七、常见性能陷阱及解决方案

问题 表现 解决方案
过度渲染 组件频繁重渲染 使用 React.memo, useMemo
长列表性能差 滚动卡顿 虚拟化列表
首屏加载慢 LCP 时间过长 代码分割, 预加载
JavaScript 阻塞 TTI 延迟 代码分割, 懒加载
状态管理不当 无关组件更新 精细化状态管理

通过综合应用这些优化策略,可以显著提升 React 应用的性能,提供更流畅的用户体验。记住,优化是一个持续的过程,需要根据应用的具体情况进行调整和迭代。

相关推荐
Dream-Y.ocean1 小时前
鸿蒙PC平台宅匠 3D 室内设计适配实战:基于 Electron 壳方案的 Three.js 双渲染引擎与参数化户型编辑器开发
javascript·3d·harmonyos
Highcharts.js2 小时前
Highcharts Gantt使用符号的自定义数据标签开发甘特图示例
javascript·甘特图·highcharts·图表开发·实战代码·响应式图表
JavaPub-rodert4 小时前
从零搭建通用管理后台:ShiyuAdmin 的 Go、React 与 RBAC 实践
开发语言·react.js·golang
kyriewen5 小时前
Skills 榜前 10 我全装了:只有 3 个能直接用
前端·javascript·程序员
工控丫丫6 小时前
帆软看板中经常使用的公式函数及经常搭的组合
前端·javascript·数据库
Dream-Y.ocean8 小时前
鸿蒙PC平台星图遥感适配实战:基于 Electron 壳方案的纯 JavaScript 遥感图像处理引擎开发
javascript·electron·harmonyos
螺丝钉tina9 小时前
[Playwright ][16]Playwright + TypeScript API 自动化测试实战:API测试
前端·javascript·typescript
Highcharts.js11 小时前
React 中原生支持使用 JSX 组件配置自定义表格 Highcharts Grid
前端·javascript·react.js·前端框架·jsx·highcharts·自定义表格
Java后端的Ai之路11 小时前
【AIAgent开发】-Agent工具封装成CLI(纯干货!!!)
java·javascript·人工智能·agent·cli
薛定谔的猫-菜鸟程序员11 小时前
Electron开发超详细教程(从入门到放弃)
前端·javascript·electron