首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Vue3和React Hooks在性能上有什么区别?

Vue3和React Hooks在性能上有什么区别?

原创
作者头像
小焱
发布2025-08-24 15:34:26
发布2025-08-24 15:34:26
1370
举报
文章被收录于专栏:前端开发前端开发

下面通过具体实例来展示 React 中的重新渲染(re-render)问题以及如何使用 useMemo 进行优化。

1. 未优化的重新渲染问题

当组件的状态或 props 变化时,React 会重新执行组件函数(重新渲染)。如果组件中有复杂计算或子组件传递了新的引用类型值,可能导致不必要的重新渲染。

代码语言:jsx
复制
import { useState } from 'react';

// 子组件:显示用户信息
const UserInfo = ({ user, onUpdate }) => {
  console.log('UserInfo 重新渲染了'); // 用于跟踪渲染
  return (
    <div>
      <p>姓名:{user.name}</p>
      <p>年龄:{user.age}</p>
      <button onClick={onUpdate}>增长年龄</button>
    </div>
  );
};

// 父组件:包含状态和计算逻辑
const App = () => {
  const [count, setCount] = useState(0);
  const [user, setUser] = useState({ name: '张三', age: 20 });

  // 复杂计算(模拟耗时操作)
  const calculateTotal = () => {
    console.log('执行了复杂计算');
    let total = 0;
    for (let i = 0; i < 100000000; i++) {
      total += i;
    }
    return total;
  };
  const total = calculateTotal();

  // 更新用户年龄的函数
  const handleUpdateAge = () => {
    setUser(prev => ({ ...prev, age: prev.age + 1 }));
  };

  return (
    <div>
      <p>计数器:{count}</p>
      <button onClick={() => setCount(c => c + 1)}>增加计数</button>
      <p>复杂计算结果:{total}</p>
      <UserInfo user={user} onUpdate={handleUpdateAge} />
    </div>
  );
};

export default App;

问题分析

  • 点击“增加计数”按钮时,count 变化会导致 App 重新渲染:
    • calculateTotal 会被重新执行(即使它的结果与 count 无关),浪费性能。
    • UserInfo 组件会重新渲染(因为父组件重新渲染时,useronUpdate 虽然值没变,但 user 是新创建的对象引用,onUpdate 是新创建的函数引用)。

2. 使用 useMemo 优化计算结果

useMemo 可以缓存计算结果,只有当依赖项变化时才重新计算,避免不必要的重复计算。

代码语言:javascript
复制
import { useState, useMemo, useCallback } from 'react';

// 子组件:用React.memo缓存,避免不必要的重渲染
const UserInfo = React.memo(({ user, onUpdate }) => {
  console.log('UserInfo 重新渲染了');
  return (
    <div>
      <p>姓名:{user.name}</p>
      <p>年龄:{user.age}</p>
      <button onClick={onUpdate}>增长年龄</button>
    </div>
  );
});

const App = () => {
  const [count, setCount] = useState(0);
  const [user, setUser] = useState({ name: '张三', age: 20 });

  // 用useMemo缓存计算结果,依赖项为空数组表示只计算一次
  const total = useMemo(() => {
    console.log('执行了复杂计算');
    let total = 0;
    for (let i = 0; i < 100000000; i++) {
      total += i;
    }
    return total;
  }, []); // 依赖项为空,只有组件首次渲染时执行

  // 用useCallback缓存函数引用,避免每次渲染创建新函数
  const handleUpdateAge = useCallback(() => {
    setUser(prev => ({ ...prev, age: prev.age + 1 }));
  }, []); // 依赖项为空,函数引用不会变化

  // 用useMemo缓存对象,避免每次渲染创建新对象
  const memoizedUser = useMemo(() => user, [user.age, user.name]);

  return (
    <div>
      <p>计数器:{count}</p>
      <button onClick={() => setCount(c => c + 1)}>增加计数</button>
      <p>复杂计算结果:{total}</p>
      <UserInfo user={memoizedUser} onUpdate={handleUpdateAge} />
    </div>
  );
};

export default App;

优化说明

  1. 优化复杂计算
    • useMemo(() => { ... }, []) 缓存了 calculateTotal 的结果,由于依赖项为空数组,该计算只会在组件首次渲染时执行,后续 count 变化不会触发重新计算。
  2. 优化子组件渲染
    • React.memo 包装 UserInfo 组件,使其只有在 props 真正变化时才重新渲染。
    • useCallback 缓存 handleUpdateAge 函数,确保每次渲染时函数引用不变(避免因函数引用变化导致子组件重渲染)。
    • useMemo 缓存 user 对象(memoizedUser),只有当 user.nameuser.age 变化时,才会创建新的对象引用。

关键结论

  • useMemo 适用于:缓存耗时的计算结果,避免重复计算。
  • 搭配使用:通常需要与 React.memo(优化组件)和 useCallback(优化函数)配合,才能彻底解决引用类型 props 导致的冗余渲染。
  • 不要过度使用:简单计算或频繁变化的值不需要缓存,useMemo 本身也有一定的性能开销。

通过这些优化,点击“增加计数”按钮时,UserInfo 不会重新渲染,calculateTotal 也不会重新执行,显著提升性能。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 未优化的重新渲染问题
  • 2. 使用 useMemo 优化计算结果
  • 优化说明
  • 关键结论
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档