React性能优化
三个可以优化的地方
避免过度多次渲染
组件会在以下情况下重新渲染
注意:例如组件组合的形式,<Test><Counter></Counter></Test>,即使Test发生了重新渲染,Counter也不会重新渲染。另外使用React这样的库或框架时,渲染指的是组件函数被调用的过程。这个过程并不一定意味着文档对象模型(DOM)实际上被更新了。它只是意味着组件的逻辑被执行,可能会重新计算组件的状态和属性。
什么是过度渲染呢?
- 无效渲染是指组件函数被调用了,但是并没有导致DOM的任何变化。
- 这通常发生在组件的状态或属性没有改变,但组件仍然被重新渲染的情况下。这种渲染是不必要的,因为它消耗了资源但没有带来任何视觉上的变化。
- 当然这在react中大部分情况下是没问题的,只有这种情况过度频繁时才会产生问题。
记忆化
组件、对象、函数都可以记忆化。
memo
工作原理
-
创建不会重新渲染的组件:
memo
用于创建一个组件,当其父组件重新渲染时,如果传入的props在两次渲染之间没有变化,那么这个被memo
包裹的组件将不会重新渲染。
-
只影响props:
memo
只对组件的props进行比较。如果一个被memo
包裹的组件在props没有变化的情况下,即使它自己的state发生了变化,或者它订阅的context发生了变化,它仍然会重新渲染。
局限性
-
在React中,每次渲染都会重新创建所有内容(包括对象和函数): 这意味着,即使组件的状态没有改变,每次渲染时,组件内部的函数和对象都会被重新实例化。
-
在JavaScript中,两个看起来相同的对象或函数实际上是不同的({} != {}): 在JavaScript中,对象和函数是引用类型。即使两个对象的内容完全相同,它们在内存中的地址也是不同的。这意味着,即使两个对象看起来一样,它们也是两个不同的实例。
-
因此,如果将对象或函数作为props传递,子组件在每次重新渲染时都会将它们视为新的props: 当父组件将对象或函数作为props传递给子组件时,由于每次渲染都会创建新的实例,子组件会认为这些props是新的,即使它们的值没有变化。
-
如果props在重新渲染之间不同,memo将不起作用:
memo
是React的一个优化技巧,它通过比较props来决定是否重新渲染组件。如果props在两次渲染之间没有变化,memo
可以防止不必要的渲染。但是,如果props是对象或函数,即使它们的值没有变化,由于它们是新创建的实例,memo
也会认为props已经改变,从而导致子组件重新渲染。
所以,我们需要对对象和函数进行memoization(记忆化),以使它们在重新渲染之间保持稳定(保持不变)。
useMemo与useCallback
工作原理
-
用于记忆化(memoize)对象和函数
-
缓存机制:
- 当你将对象或函数传递给
useMemo
或useCallback
时,这些值或函数会被存储在内存中(即被“缓存”)。在随后的重新渲染中,只要依赖项(即“输入”)没有变化,就会返回缓存的值或函数。
- 当你将对象或函数传递给
-
依赖数组:
useMemo
和useCallback
都接受一个依赖数组,这与useEffect
的工作方式类似。依赖数组用于追踪哪些值或状态影响到了记忆化的值或函数。- 如果依赖数组中的任何一个值发生变化,那么记忆化的值或函数就会被重新创建。这是通过比较新旧依赖项来实现的,只有当依赖项发生变化时,才会触发重新计算。
使用场景
-
防止不必要的渲染:
- 通过与
React.memo
一起使用,可以记忆化 props,以避免不必要的组件重新渲染。
- 通过与
-
避免每次渲染时的昂贵重新计算:
- 使用
useMemo
来记忆化那些计算成本较高的值。这样,只有在其依赖项发生变化时,才会重新计算这些值,从而节省性能。
- 使用
-
记忆化在其他 Hook 的依赖数组中使用的值:
- 当某个值被用作另一个 Hook(如
useEffect
)的依赖数组中的项时,使用useMemo
或useCallback
来记忆化这个值可以避免无限循环的副作用。例如,如果你在useEffect
的依赖数组中直接使用一个会不断变化的值,可能会导致无限循环的副作用执行。通过记忆化这个值,你可以确保只有当值实际改变时,副作用才会重新运行。
- 当某个值被用作另一个 Hook(如
案例
假设我们再App.js中有以下对象和函数,使用了useMemo与useCallback:
const [isFakeDark, setIsFakeDark] = useState(false);const [posts, setPosts] = useState(() =>Array.from({ length: 30 }, () => createRandomPost()));const handleAddPost = useCallback(function handleAddPost(post) {setPosts((posts) => [post, ...posts]);}, []);const archiveOptions = useMemo(() => {return {show: false,title: `Post archive in addition to ${posts.length} main posts`,};}, [posts.length]);<ArchivearchiveOptions={archiveOptions}onAddPost={handleAddPost}setIsFakeDark={setIsFakeDark}/>
注意下useMemo与useCallback使用方式的细微差别。
Archive使用memo如下所示:
const Archive = memo(function Archive({ archiveOptions, onAddPost }) {// Here we don't need the setter function. We're only using state to store these posts because the callback function passed into useState (which generates the posts) is only called once, on the initial render. So we use this trick as an optimization technique, because if we just used a regular variable, these posts would be re-created on every render. We could also move the posts outside the components, but I wanted to show you this trick 😉const [posts] = useState(() =>// 💥 WARNING: This might make your computer slow! Try a smaller `length` firstArray.from({ length: 30000 }, () => createRandomPost()));const [showArchive, setShowArchive] = useState(archiveOptions.show);return (<aside><h2>{archiveOptions.title}</h2><button onClick={() => setShowArchive((s) => !s)}>{showArchive ? "Hide archive posts" : "Show archive posts"}</button>{showArchive && (<ul>{posts.map((post, i) => (<li key={i}><p><strong>{post.title}:</strong> {post.body}</p><button onClick={() => onAddPost(post)}>Add as new post</button></li>))}</ul>)}</aside>);
});
注意: 对于state的set函数来说,它不需要useCallback函数,它本身随着渲染就不会改变地址。
减小Bundle大小
Bundle与Bundle分别是什么?
代码分割
代码分割(Code splitting)是一种在现代前端工程中常用的优化技术,它允许将应用程序的代码库分割成多个小块(bundles),这些小块可以独立于主代码库进行加载。这种方法特别适用于大型应用程序,可以显著提高加载速度和性能
路由级别代码分割
转变为
Suspense是一个用于处理异步组件加载的组件。它允许你定义一个边界,当其子组件在加载过程中遇到异步操作(如数据获取)而暂停时,可以显示一个备用内容(fallback)。然后Suspense与React的lazy
函数结合使用,实现组件的懒加载。这种方式允许你在组件首次渲染时自动触发组件的加载,同时在加载过程中显示一个占位符。
因为懒加载的元素,当你切换到Login或者Pricing等页面的时候, 对应的js的代码块才刚刚从服务器下载过来,需要时间到达客户端。这个时候suspense组件就起到了作用!
相关文章:
React性能优化
三个可以优化的地方 避免过度多次渲染 组件会在以下情况下重新渲染 注意:例如组件组合的形式,<Test><Counter></Counter></Test>,即使Test发生了重新渲染,Counter也不会重新渲染。另外使用React这样的库或框架时&a…...
Django之ORM
1.ORM介绍 ORM概念 对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术。 简单的说,ORM是通过使用描述对象和数据库之间映射的元数据,将程序中的对…...
macos上设置windsurf命令行启动
解决方案 1. 在/usr/local/bin 目录下创建软链 sudo ln -s /Applications/Windsurf.app/Contents/Resources/app/bin/windsurf /usr/local/bin/windsurf 2. 执行source source ~/.zshrc...
一、web基础和http协议
前言 https://www.baidu.com/:URL(是一种万维网寻址网址) https://:协议,加密的http,加密的超文本传输协议,在数据传输之前要通过整数进行身份验证,验证通过才可以进行数据传输。 …...
Can‘t find variable: token(token is not defined)
文章目录 例子 1:使用 var例子 2:使用 let 或 const例子 3:异步操作你的代码中的情况 Cant find variable: tokentoken is not defined源代码 // index.jsPage({data: {products:[],cardLayout: grid, // 默认卡片布局为网格模式isGrid: tr…...
Elasticsearch ILM 故障排除:常见问题及修复
作者:来自 Elastic Stef Nestor 大家好!我们的 Elasticsearch 团队正在不断改进我们的索引生命周期管理 (index Lifecycle Management - ILM) 功能。当我第一次加入 Elastic Support 时,我通过我们的使用 ILM 实现自动滚动教程快速上手。在帮…...
1. 设计模式的由来
设计模式的灵感来自建筑师亚历山大的“设计套路”,后来被程序员借用,总结出一套“编程武功秘籍”。 20世纪90年代,四位软件工程师(被称为“四人帮”)——Erich Gamma、Richard Helm、Ralph Johnson 和 John Vlissides&…...
【Excel】Excel中将日期格式转换为文本格式,并按日期显示。
【问题需求】 在使用excel进行数据导入的过程中, 有的软件要求日期列必须是文本格式。 但是直接将日期列的格式改为文本后,显示一串数字,而不按日期显示。 进而无法导入使用。 【解决方法】 使用【TXET】函数公式进行处理, 在单独…...
SpringBoot入门:如何新建SpringBoot项目(保姆级教程)
在本文中,我们将演示如何新建一个基本的 Spring Boot 项目。写这篇文章的时候我还是很惊讶的,因为我发现有些java的初学者,甚至工作10年的老员工居然并不会新建一个SpringBoot项目,所以特别出了一篇文章来教大家新建一个SpringBoo…...
什么是Layer Normalization?
一、概念 前面的文章中,我们介绍了Batch Normalization。BN的目的是使得每个batch的输入数据在每个维度上的均值为0、方差为1(batch内,数据维度A的所有数值均值为0、方差为1,维度B、C等以此类推),这是由于神…...
基于神经网络的弹弹堂类游戏弹道快速预测
目录 一、 目的... 1 1.1 输入与输出.... 1 1.2 隐网络架构设计.... 1 1.3 激活函数与损失函数.... 1 二、 训练... 2 2.1 数据加载与预处理.... 2 2.2 训练过程.... 2 2.3 训练参数与设置.... 2 三、 测试与分析... 2 3.1 性能对比.... 2 3.2 训练过程差异.... 3 四、…...
ASP.NET CORE API 解决跨域问题
环境 vs2022 .net 8 创建ASP.net Core API项目 配置跨域 编写ApiController 启动项目 得到服务器运行的 地址 在Hbuiler中创建web项目,编写代码 【运行】-【运行到浏览器】-选择一个浏览器,查看结果 正常显示 问题 如果允许所有源访问,有安全风险方…...
西安理工大学丨ChatGPT助力学术论文写作训练营-助力发表SCI一区、二区
在当今学术研究中,科研人员在撰写论文时面临诸多挑战。首先是信息量的剧增,科研人员需要快速消化新知识,筛选相关信息并清晰表达。但论文写作不仅是信息的罗列,还需要条理清晰、逻辑严密、语言精准,特别是在竞争激烈的…...
Android hid 数据传输(device 端 )
最近一直在处理hid 数据需求,简而言之就是两台设备直接可以通过usb 线互相传递数据。 项目架构 为什么Device 端要采用HID(人机接口设备)的方式发送和接收数据呢? 主要是速度快,举个例子,就是鼠标移动&am…...
Facebook 人工智能:重塑社交新未来
在数字化迅速发展的今天,人工智能(AI)已经深入了我们的生活,尤其是在社交媒体领域。Facebook作为全球最大的社交平台之一,正利用AI技术,革新其服务和用户体验,为用户打造社交互动的新未来。 首先,人工智能…...
UIlicious - 自动化端到端测试
在现代软件开发中,测试自动化已然成为产品交付质量的基石。而端到端测试(E2E),作为验证整个应用流畅运行的关键,常常是测试工作中最具挑战性的一环。这时,一款简单高效的自动化测试工具——UIlicious&#…...
PHP 与 MySQL 搭配的优势
一、PHP 与 MySQL 搭配的优势 强大的动态网页开发能力 PHP 是一种服务器端脚本语言,能够生成动态网页内容。它可以根据用户的请求、数据库中的数据等因素,实时地生成 HTML 页面返回给客户端浏览器。而 MySQL 是一个流行的关系型数据库管理系统…...
HDFS 操作命令
在现代的企业环境中,单机容量往往无法存储大量数据,需要跨机器存储。统一管理分布在 集群上的文件系统称为 分布式文件系统 。 HDFS ( Hadoop Distributed File System )是 Apache Hadoop 项目的一个子项目, Hadoo…...
第四篇:k8s 理解Service工作原理
什么是service? Service是将运行在一组 Pods 上的应用程序公开为网络服务的抽象方法。 简单来说K8s提供了service对象来访问pod。我们在《k8s网络模型与集群通信》中也说过k8s集群中的每一个Pod(最小调度单位)都有自己的IP地址,都…...
什么是TCP的三次握手?
TCP的三次握手:深入理解建立可靠连接的过程 引言 在计算机网络中,传输控制协议(TCP)是确保数据可靠传输的核心协议之一。TCP通过三次握手机制来建立一个稳定的、双向的连接,这对于确保数据的完整性和顺序至关重要。本…...
Pytorch使用手册- TorchVision目标检测微调Tutorial的使用指南(专题十二)
这篇教程的目标是对一个预训练的 Mask R-CNN 模型进行微调,应用于 Penn-Fudan 行人检测与分割数据集。该数据集包含 170 张图像,里面有 345 个行人实例,我们将通过这个教程来演示如何使用 torchvision 中的新特性,训练一个面向自定义数据集的目标检测和实例分割模型。 注意…...
Modern Effective C++条款三十五:优先考虑基于任务的编程而非基于线程的编程
C中开发者可以通过两种主要方式异步执行一个函数,如doAsyncWork()。这两种方法分别是基于线程(thread-based)和基于任务(task-based)的方式。 基于线程的方式 使用std::thread创建一个新的线程来执行doAsyncWork()函数,直接且直观,但也有其…...
lyapunov指数的绘制
有如下方程: %% 方程式 % x(n1)1y(n)-a*x(n)^2 % y(n1)b*x(n)绘制其对应的lyapunov指数。 MATLAB实现方式: clc; clearvars; close all;%% 方程式 % x(n1)1y(n)-a*x(n)^2 % y(n1)b*x(n)%% 代码 N 1000; a (0:0.001:1.4); b 0.3; na length(a…...
WPF+MVVM案例实战与特效(三十二)- 封装一个Appconfig 操作类(保留注释)
文章目录 1、概述2、ConfigHelper 的功能3、代码实现1、ConfigHelper.cs 代码2、帮助类使用4、总结1、概述 在开发 WPF 应用程序时,配置文件(如 App.config )是存储应用程序设置、连接字符串和其他运行时信息的常用方式。然而,直接操作这些配置文件可能会涉及到复杂的 XML…...
决策树:ID3、C4.5和CART特征选择方式
1 前言 该文章主要目的是记录ID3、C4.5和CART特征选择方式,这里只对决策树进行简单介绍。 决策树(Decision Tree)算法是一种有监督学习算法,它利用分类的思想,根据数据的特征构建数学模型,从而达到数据的筛…...
02 conda常用指令
目录 命令快速查找命令详细解释列出当前conda中存在的解释器环境使用指定的解释器环境创建虚拟环境激活自己创建的虚拟环境虚拟环境删除切换回主环境找到你计算机中安装的miniconda3的跟目录找到虚拟环境的目录选择需要删除的虚拟环境文件夹确认环境是否删除 补充删除虚拟环境指…...
从仪表盘探索 MongoDB 关键指标
这是 MongoDB 监控系列文章的第七篇,前面几篇文章的链接如下: MongoDB 监控(一)MongoDB 监控(二)MongoDB 监控(三)MongoDB 监控(四)MongoDB 监控(…...
Grule前端表单post后端执行grule引擎规则
Grule前端表单post后端执行grule引擎规则 编写前端表单和后端接口 编写test.go执行grule引擎规则 示例都是 go test 执行的测试代码,所以将里面的测试代码去除 由于之前 NumberExponentExample_test.go 已经验证可运行, 所以将 err 的异常处理去除 package mai…...
EasyRTC支持嵌入式智能硬件与微信小程序实时通话
基础建设如此发达的时代,各种物联网设备都越来越普及,尤其是可穿戴设备和智能家居设备的发展,而在物联网设备中,视频物联网设备又是特别受人关注的设备,因为他们具备有看得见的属性,像智能家居里面的摄像头…...
openGauss开源数据库实战十九
文章目录 任务十九 openGauss DML 语句测试任务目标实施步骤一、准备工作二、INSERT语句三、DELETE语句四、UPDATE语句五、清理工作 任务十九 openGauss DML 语句测试 任务目标 掌握DML语句的用法,包括INSERT语句、DELETE语句和UPDATE语句。 实施步骤 一、准备工作 使用Li…...
基于XML的AOP开发
AOP 为 Aspect Oriented Programming 的缩写,意思为面向切面编程。 AOP相关术语: 目标对象(Target): 你要去代理的对象,可以理解为之前很单纯的那个对象。 代理对象(Proxy): 你把你那个单纯的对象给我,…...
获取Ubuntu-22.04.1 对应的vmlinux文件
0.前言 🚀write in front🚀 🔎大家好,我是黄桃罐头,希望你看完之后,能对你有所帮助,不足请指正!共同学习交流 🎁欢迎各位→点赞👍 收藏⭐️ 留言…...
Python后端 -- 万字长文全面解析Django框架
自从2005年诞生以来,Django因其“开发速度快、安全性高”的特点迅速成为许多开发者的首选。无论是小型的个人项目,还是大型的企业应用,Django都能游刃有余地满足需求。我们将从Django的基础知识带你全面掌握Django,从基础知识到高…...
“指标管理系统”是什么?企业如何搭建指标管理系统?
在当今数字化时代,数据已成为企业决策的重要依据。然而,海量数据中如何筛选出关键指标,并对其进行有效管理,成为了众多企业面临的难题。为此,指标管理系统应运而生,它旨在帮助企业规范化定义、统一管理和高…...
Node.js简单接口实现教程
Node.js简单接口实现教程 1. 准备工作 确保您的计算机已安装: Node.js (建议版本16.x以上)npm (Node包管理器) 2. 项目初始化 # 创建项目目录 mkdir nodejs-api-tutorial cd nodejs-api-tutorial# 初始化npm项目 npm init -y# 安装必要依赖 npm install expres…...
交换机四大镜像(端口镜像、流镜像、VLAN镜像、MAC镜像)应用场景、配置实例及区别对比
在网络管理中,端口镜像、流镜像、VLAN镜像和MAC镜像都是用于监控和分析网络流量的重要技术。 端口镜像(Port Mirroring) 定义:端口镜像是将一个或多个源端口的流量复制到一个目标端口,以便于网络管理员能够监控和分析…...
服务器上的常见Linux命令教程
在管理服务器(如香港服务器)时,掌握常见的 Linux 命令 是非常重要的,它们可以帮助你高效地完成服务器管理任务,如文件操作、进程管理、用户管理、网络配置等。 以下是一个系统化的 Linux 常见命令教程,分为…...
聚合支付系统/官方个人免签系统/三方支付系统稳定安全高并发 附教程
聚合支付系统/官方个人免签系统/三方支付系统稳定安全高并发 附教程 系统采用FastAdmin框架独立全新开发,安全稳定,系统支持代理、商户、码商等业务逻辑。 针对最近一些JD,TB等业务定制,子账号业务逻辑API 非常详细,方便内置…...
【MySQL】使用 JDBC 连接数据库
文章目录 前言1. 认识 JDBC 1.1 概念1.2 好处 2. 使用 JDBC 2.1 安装数据驱动包2.2 把 jar 包导入到项目中2.3 代码编写2.4 测试结果 3. 代码优化4. 源码展示结语 前言 在 MySQL 系列中,我们介绍了很多内容,包括但不限于建库建表,增删查改等…...
深入浅出:PHP会话管理(Session 和 Cookie)
深入浅出:PHP会话管理(Session 和 Cookie) 前言 在Web开发中,会话管理是确保用户状态持续性和数据安全的关键。通过会话管理,我们可以在多个页面请求之间保持用户的登录状态、购物车信息等。PHP提供了两种主要的会话…...
Logistic Regression(逻辑回归)、Maximum Likelihood Estimatio(最大似然估计)
Logistic Regression(逻辑回归)、Maximum Likelihood Estimatio(最大似然估计) 逻辑回归(Logistic Regression,LR)逻辑回归的基本思想逻辑回归模型逻辑回归的目标最大似然估计优化方法 逻辑回归…...
【开源】A063—基于Spring Boot的农产品直卖平台的设计与实现
🙊作者简介:在校研究生,拥有计算机专业的研究生开发团队,分享技术代码帮助学生学习,独立完成自己的网站项目。 代码可以查看项目链接获取⬇️,记得注明来意哦~🌹 赠送计算机毕业设计600个选题ex…...
单链表---合并两个链表
将两个升序链表合并为一个新的升序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 struct ListNode {int val;struct ListNode* next; }; w 方法一---不使用哨兵位 我们创建一个新链表用于合并两个升序链表, 将两个链表中最小的结点依次尾插到…...
draggable插件——实现元素的拖动排序——拖动和不可拖动的两种情况处理
最近在写后台管理系统的时候,遇到一个需求,就是关于拖动排序的功能。 我之前是写过一个关于拖动表格的功能,此功能可以实现表格中的每一行数据上下拖动实现排序的效果。 vue——实现表格的拖拽排序功能——技能提升 但是目前我这边的需求是…...
vite+vue3 配置ip和端口以及自动打开浏览器
编辑文件vite.config.ts 修改前vite.config.ts文件内容 import { defineConfig } from vite import vue from vitejs/plugin-vue// https://vite.dev/config/ export default defineConfig({plugins: [vue()], })修改vite.config.ts后文件内容 新增server内容 server:{host…...
Netty面试内容整理-Netty 概述
Netty 是一个基于 Java 的异步事件驱动网络应用框架,常用于构建高性能、高并发的网络服务。Netty 封装了 Java NIO 的复杂细节,使得开发者可以方便地构建高效的网络应用。以下是 Netty 的概述: Netty 的特点 ● 异步和事件驱动:Netty 采用异步非阻塞的 I/O 模型,基于事件驱…...
Docker搭建达梦数据库--基于 X86 架构
1、部署环境 X86_64 架构的服务器 1 台,安装好docker 拉取镜像 官方最新非授权版本有些函数方法无法使用 docker pull registry.cn-hangzhou.aliyuncs.com/qiluo-images/dm8_single:dm8_20230808_rev197096_x86_rh6_64查看镜像 docker images | grep dm8运行容器 docker run…...
4. 设计模式分类
4.1 创建型模式 这类模式提供创建对象的机制,能够提升已有代码的灵活性和可复用性。 序 号 类 型 业务场景 实现要点 1 工 厂 方 法 多种类型商品不同接口,统一发奖服 务搭建场景 定义一个创建对象的接口,让其子类自 己决定实例化哪一个工厂类,工厂模式 使其创建过程延迟…...
【SKFramework框架核心模块】3-12、网络请求模块
推荐阅读 CSDN主页GitHub开源地址Unity3D插件分享QQ群:398291828小红书小破站 大家好,我是佛系工程师☆恬静的小魔龙☆,不定时更新Unity开发技巧,觉得有用记得一键三连哦。 一、前言 【Unity3D框架】SKFramework框架完全教程《全…...
MacOS安装软件后无法启动报错:“已损坏,无法打开,你应该将它移到废纸篓“
目录 报错截图 解决方法 知识科普 报错截图 解决方法 1. 打开系统设置->安全性与隐私->选择任何来源 2. 如果打开没有看到"任何来源",如果不开启“任何来源”的选项,会直接影响到无法运行的第三方应用。开启“任何来源”的方法如下&a…...