当前位置: 首页 > article >正文

第五节:React Hooks进阶篇-如何用useMemo/useCallback优化性能

  • 反模式:滥用导致的内存开销
  • React 19编译器自动Memoization原理

React Hooks 性能优化进阶:从手动到自动 Memoization

(基于 React 18 及以下版本,结合 React 19 新特性分析)


一、useMemo/useCallback 的正确使用场景与优化策略

1. useMemo:缓存高开销计算结果

核心作用:避免每次渲染重复执行复杂计算(如数据过滤、数学运算)。
正确用法

const filteredList = useMemo(() => bigDataList.filter(item => item.category === activeCategory), [bigDataList, activeCategory] // 仅依赖变化时重新计算
);

适用场景
• 数据量大的列表过滤/排序
• 复杂对象/数组的派生状态(如用户权限树、图表数据预处理)
• 需稳定引用的对象(避免子组件因引用变化重新渲染)

2. useCallback:稳定函数引用

核心作用:避免函数因引用变化导致子组件无效渲染。
正确用法

const handleSubmit = useCallback((values) => api.postForm(values), [] // 空依赖:函数逻辑不依赖外部变量
);

适用场景
• 事件处理函数传递给 React.memo 优化的子组件
• 依赖闭包值的异步操作(如定时器、防抖函数)


二、反模式:滥用导致的性能陷阱

1. 过度缓存导致内存开销

问题:对简单计算或频繁变化的值使用 useMemo,反而增加内存和比较成本
示例

// ❌ 错误:简单计算无需缓存
const total = useMemo(() => a + b, [a, b]); 
2. 依赖项管理不当

缺失依赖:导致闭包中引用过期值

const [count, setCount] = useState(0);
const increment = useCallback(() => {setCount(count + 1); // ❌ 依赖缺失,始终基于初始count
}, []); 

冗余依赖

const fetchData = useCallback(() => {getData(userId); 
}, [userId, getData]); // ❌ getData若为稳定引用(如来自useCallback),则无需重复依赖
3. 忽略组件拆分优化

问题:依赖 useMemo 缓存大型组件渲染结果,而非拆分细粒度组件
优化方案

// ✅ 拆分子组件并用 React.memo 优化
const ExpensiveSection = memo(({ data }) => <div>{data}</div>);

三、React 19 编译器自动 Memoization 原理与影响

1. 自动优化的核心机制

智能依赖追踪:编译器静态分析组件代码,自动识别变量间的依赖关系
函数稳定性保证:即使父组件重新渲染,若函数逻辑未变化,编译器自动保持引用稳定
计算缓存:自动对高开销操作(如数组遍历、复杂运算)实施类似 useMemo 的优化

2. 开发者行为变化

代码简化:不再需要手动添加 useMemo/useCallback

// React 19 ✅ 自动优化
const filteredList = bigData.filter(item => item.category === activeCategory);

例外场景
• 第三方库依赖严格引用相等性(如某些动画库)
• 超高频更新场景(如实时游戏引擎)需手动干预

3. 性能优化优先级调整

优先策略

  1. 保持代码简洁,依赖编译器自动优化
  2. 使用性能分析工具定位真实瓶颈(如 React DevTools)
  3. 仅在必要时手动添加 Memoization

四、新旧版本性能优化对比

优化维度React 18(手动)React 19(自动)
代码复杂度高(需显式声明依赖和缓存)低(编译器自动处理)
内存占用可能因过度缓存增加按需优化,减少冗余缓存
维护成本高(需持续监控依赖关系)低(聚焦业务逻辑)
适用场景所有场景除极端性能敏感场景外全覆盖

五、最佳实践总结

  1. React 18 及以下版本
    • 对高频计算/函数传递场景精准使用 useMemo/useCallback
    • 通过 memo + useCallback 避免深层子组件无效渲染
  2. React 19 及以上版本
    • 优先编写直观代码,信任编译器优化能力
    • 升级后逐步移除冗余 Memoization 代码
  3. 通用原则
    • 避免过早优化,先用工具验证性能瓶颈
    • 保持组件细粒度化,减少单组件渲染压力

通过合理运用手动优化与编译器自动能力,可显著提升应用性能与代码可维护性。

相关文章:

第五节:React Hooks进阶篇-如何用useMemo/useCallback优化性能

反模式&#xff1a;滥用导致的内存开销React 19编译器自动Memoization原理 React Hooks 性能优化进阶&#xff1a;从手动到自动 Memoization &#xff08;基于 React 18 及以下版本&#xff0c;结合 React 19 新特性分析&#xff09; 一、useMemo/useCallback 的正确使用场景…...

STL迭代器:C++泛型编程的核心工具 [特殊字符]

在C中&#xff0c;STL&#xff08;标准模板库&#xff09;的迭代器是泛型编程的核心&#xff0c;它不仅解决了指针的局限性&#xff0c;还为算法与容器之间提供了抽象的访问接口。接下来&#xff0c;我们将探讨迭代器的核心作用、与指针的关键区别以及其设计哲学。 一、迭代器的…...

ffmpeg无损转格式的命令行

将ffmpeg.exe拖入命令行窗口 c:\users\zhangsan>D:\ffmpeg-2025-03-11\bin\ffmpeg.exe -i happy.mp4 -c:v copy -c:a copy 格式转换后.mkv -c:v copy 仅做拷贝视频,不重新编码 -c:a copy 仅做拷贝音频 ,不重新编码...

Monorepo 是什么?前端项目的多模块管理终极方案

前言 你是否曾经维护过多个前端项目?是否在多个项目之间来回复制粘贴组件,工具函数?是否经常被"组件更新没同步","构建时间太长","依赖版本冲突"等问题困扰? 这些问题都指向一个关键点: 项目结构和管理方式 今天,我来聊聊一种非常火但又容…...

对象池模式在uniapp鸿蒙APP中的深度应用

文章目录 对象池模式在uniapp鸿蒙APP中的深度应用指南一、对象池模式核心概念1.1 什么是对象池模式&#xff1f;1.2 为什么在鸿蒙APP中需要对象池&#xff1f;1.3 性能对比数据 二、uniapp中的对象池完整实现2.1 基础对象池实现2.1.1 核心代码结构2.1.2 在Vue组件中的应用 2.2 …...

条款05:了解C++默默编写并调用哪些函数

目录 1.默认生成的函数 2.无法生成的情况 2.1当成员函数有引用 或者 被const修饰 2.2.operator在基类被私有 1.默认生成的函数 class empty {};//相当于class empty { public:empty(){ ... } // 构造函数empty(const empty& rhs) { ... }// 拷贝构造~empty(){ ... } //…...

PythonFlask打造高效流式接口的实战

一、环境搭建与项目初始化 要使用 Flask 提供流式接口,首先得确保开发环境正确配置。在 Ubuntu 系统上,可借助 apt 包管理器便捷安装 Python 和 pip: sudo apt update sudo apt install python3 python3-pip对于 Windows 用户,推荐从官网下载安装包进行安装。安装完成后,…...

强化学习算法系列(五):最主流的算法框架——Actor-Critic算法框架

强化学习算法 &#xff08;一&#xff09;动态规划方法——策略迭代算法(PI)和值迭代算法(VI) &#xff08;二&#xff09;Model-Free类方法——蒙特卡洛算法(MC)和时序差分算法(TD) &#xff08;三&#xff09;基于动作值的算法——Sarsa算法与Q-Learning算法 &#xff08;四…...

设计模式(结构型)-桥接模式

目录 摘要 定义 类图 角色 具体实现 优缺点 优点 缺点 使用场景 使用案例 JDBC 和桥接模式 总结 摘要 在软件开发领域&#xff0c;随着系统规模和复杂性的不断攀升&#xff0c;如何设计出具有良好扩展性、灵活性以及可维护性的软件架构成为关键挑战。桥接模式作为一…...

【MySQL】MySQL数据库 —— 简单认识

目录 1. 数据库的介绍 1.1 什么是数据库 1.2 数据库和数据结构之间关系 2. 数据库分类 2.1 关系型数据库&#xff08;RDBMS&#xff09; 2.2 非关系型数据库 2.3 区别 一些行内名词简单解释&#xff1a; 3. 关于mysql 主要学什么 4. MySQL中重要的概念 4.1 概念 4…...

RNN - 语言模型

语言模型 给定文本序列 x 1 , … , x T x_1, \ldots, x_T x1​,…,xT​&#xff0c;语言模型的目标是估计联合概率 p ( x 1 , … , x T ) p(x_1, \ldots, x_T) p(x1​,…,xT​)它的应用包括 做预训练模型&#xff08;eg BERT&#xff0c;GPT-3&#xff09;生成本文&#xff…...

过拟合、归一化、正则化、鞍点

过拟合 过拟合的本质原因往往是因为模型具备方差很大的权重参数。 定义一个有4个特征的输入&#xff0c;特征向量为,定义一个模型&#xff0c;其只有4个参数&#xff0c;表示为。当模型过拟合时&#xff0c;这四个权重参数的方差会很大&#xff0c;可以假设为。当经过这个模型后…...

【python画图】:从入门到精通绘制完美柱状图

目录 Python数据可视化&#xff1a;从入门到精通绘制完美柱状图一、基础篇&#xff1a;快速绘制柱状图1.1 使用Matplotlib基础绘制1.2 使用Pandas快速绘图 二、进阶篇&#xff1a;专业级柱状图定制2.1 多系列柱状图2.2 堆叠柱状图2.3 水平柱状图 三、专业参数速查表Matplotlib …...

基础知识:离线安装docker、docker compose

(1)离线安装docker 确认版本:Ubuntu 18.04 LTS - bionic 确认架构:X86_64 lsb_release -a uname -a 官方指南:https://docs.docker.com/engine/install/ 选择Ubuntu,发现页面上最低是Ubuntu20.04, 不要紧...

畅游Diffusion数字人(27):解读字节跳动提出主题定制视频生成技术Phantom

畅游Diffusion数字人(0):专栏文章导航 前言:主题定制视频生成,特别是zero-shot主题定制视频生成,一直是当前领域的一个难点,之前的方法效果很差。字节跳动提出了一个技术主题定制视频生成技术Phantom,效果相比于之前的技术进步非常显著。这篇博客详细解读一下这一工作。 …...

《Adaptive Layer-skipping in Pre-trained LLMs》- 论文笔记

作者&#xff1a;Xuan Luo, Weizhi Wang, Xifeng Yan Department of Computer Science, UC Santa Barbara xuan_luoucsb.edu, weizhiwangucsb.edu, xyancs.ucsb.edu 1. 引言与动机 1.1 背景 LLM 的成功与挑战: 大型语言模型 (LLMs) 在翻译、代码生成、推理等任务上取得巨大成…...

阅读分析Linux0.11 /boot/head.s

目录 初始化IDT、IDTR和GDT、GDTR检查协处理器并设置CR0寄存器初始化页表和CR3寄存器&#xff0c;开启分页 初始化IDT、IDTR和GDT、GDTR startup_32:movl $0x10,%eaxmov %ax,%dsmov %ax,%esmov %ax,%fsmov %ax,%gslss _stack_start,%espcall setup_idtcall setup_gdtmovl $0x1…...

android11 DevicePolicyManager浅析

目录 &#x1f4d8; 简单定义 &#x1f4d8;应用启用设备管理者 &#x1f4c2; 文件位置 &#x1f9e0; DevicePolicyManager 功能分类举例 &#x1f6e1;️ 1. 安全策略控制 &#x1f4f7; 2. 控制硬件功能 &#x1f9f0; 3. 应用管理 &#x1f512; 4. 用户管理 &am…...

《前端性能优化秘籍:打造极致用户体验》

在当下&#xff0c;网站和应用的性能表现直接关乎用户去留。快速加载、流畅交互的页面能让用户沉浸其中&#xff0c;反之&#xff0c;缓慢的响应速度则会让他们毫不犹豫地离开。对于前端开发者而言&#xff0c;性能优化不仅是技术追求&#xff0c;更是提升用户体验、增强产品竞…...

微信小程序实现table样式,自带合并行合并列

微信小程序在代码编写过程好像不支持原生table的使用&#xff0c;在开发过程中偶尔又得需要拿table来展示。 1.table效果展示 1.wxml <view class"table-container"><view class"table"><view class"table-row"><view cla…...

学习笔记十二——Rust 高阶函数彻底入门(超详细过程解析 + 每步数值追踪)

&#x1f4a1; 彻底搞懂 Rust 高阶函数&#xff01;新手最容易卡住的语法 调用流程全讲透&#xff08;含逐步拆解&#xff09; Rust 函数式编程中有一个常见却经常让人懵的概念&#xff1a;高阶函数&#xff08;Higher-Order Function&#xff09; 一看到 fn(i32) -> i32、…...

电脑的品牌和配置

我的笔记本是2020年买的&#xff0c;之前的订单找不到了&#xff0c;就知道是联想&#xff0c;不清楚具体的配置。 本文来源&#xff1a;腾讯元宝 检查系统信息&#xff08;Windows&#xff09; 这通常是 ​​联想&#xff08;Lenovo&#xff09;​​ 的型号代码。 81XV 是联想…...

Redis面试——常用命令

一、String &#xff08;1&#xff09;设置值相关命令 1.1.1 SET 功能&#xff1a;设置一个键值对&#xff0c;如果键已存在则覆盖旧值语法&#xff1a; SET key value [EX seconds] [PX milliseconds] [NX|XX]EX seconds&#xff1a;设置键的过期时间为 seconds 秒 PX milli…...

Swin-Transformer-UNet改进:融合Global-Local Spatial Attention (GLSA) 模块详解

目录 1.模块概述 2.swinUNet网络 3. 完整代码 1.模块概述 Global-Local Spatial Attention (GLSA) 是一种先进的注意力机制模块,专为计算机视觉任务设计,能够同时捕捉全局上下文信息和局部细节特征。 该模块通过创新的双分支结构和自适应融合机制,显著提升了特征表示能…...

ubuntu 向右拖动窗口后消失了、找不到了

这是目前单显示器的设置&#xff0c;因为实际只有1个显示器&#xff0c;之前的设置如下图所示&#xff0c;有2个显示器&#xff0c;一个主显示器&#xff0c;一个23寸的显示器 ubuntu 22.04 系统 今天在操作窗口时&#xff0c;向右一滑&#xff0c;发现这个窗口再也不显示了、找…...

大语言模型(LLMs)中的强化学习(Reinforcement Learning, RL)

第一部分&#xff1a;强化学习基础回顾 在深入探讨LLMs中的强化学习之前&#xff0c;我们先快速回顾一下强化学习的核心概念&#xff0c;确保基础扎实。 1. 强化学习是什么&#xff1f; 强化学习是一种机器学习范式&#xff0c;目标是让智能体&#xff08;Agent&#xff09;…...

2025最新版微软GraphRAG 2.0.0本地部署教程:基于Ollama快速构建知识图谱

一、前言 微软近期发布了知识图谱工具 GraphRAG 2.0.0&#xff0c;支持基于本地大模型&#xff08;Ollama&#xff09;快速构建知识图谱&#xff0c;显著提升了RAG&#xff08;检索增强生成&#xff09;的效果。本文手把手教你如何从零部署&#xff0c;并附踩坑记录和性能实测…...

泛型算法——只读算法(一)

在 C 标准库中&#xff0c;泛型算法的“只读算法”指那些 不会改变它们所操作的容器中的元素&#xff0c;仅用于访问或获取信息的算法&#xff0c;例如查找、计数、遍历等操作。 accumulate std::accumulate()是 C 标准库**numeric**头文件中提供的算法&#xff0c;用于对序列…...

Redis的常见数据类型

Redis 提供了多种数据类型&#xff0c;以满足不同的应用场景。以下是 Redis 的主要数据类型及其应用场景&#xff1a; 字符串&#xff08;String&#xff09;&#xff1a; 描述&#xff1a;最基本的数据类型&#xff0c;存储单个键值对&#xff0c;值可以是字符串、整数或浮点数…...

Mybatis中dao(mapper)层几种传参方式

一、SQL语句中接收参数的方式有两种&#xff1a; 1、 #{}预编译 &#xff08;可防止sql注入&#xff09; 2、${}非预编译&#xff08;直接拼接sql&#xff0c;不能防止sql注入&#xff09; #{}和${}的区别是什么? #{} 占位符&#xff0c;相当于?&#xff0c;sql预编译&…...