一七一、React性能优化方式
在 React 中进行性能优化可以通过多种手段来减少渲染次数、优化渲染效率并减少内存消耗。以下是常见的性能优化方法及示例:
1. shouldComponentUpdate
shouldComponentUpdate 是类组件中的生命周期方法,它可以让组件在判断是否需要重新渲染时,避免不必要的渲染:
class MyComponent extends React.Component {shouldComponentUpdate(nextProps, nextState) {// 只有当 props 或 state 发生变化时才重新渲染return nextProps.value !== this.props.value || nextState.count !== this.state.count;}render() {return <div>{this.props.value}</div>;}
}
在这个示例中,组件只有在 value 或 count 发生变化时才会重新渲染,这样可以避免不必要的渲染,提高性能。
2. PureComponent
PureComponent 是类组件的替代方案,使用浅层比较 props 和 state 来确定是否重新渲染。它相当于内置了 shouldComponentUpdate 的优化:
import React, { PureComponent } from 'react';class MyPureComponent extends PureComponent {render() {return <div>{this.props.value}</div>;}
}
PureComponent 自动实现了浅比较(shallow comparison),如果 props 和 state 没有变化,就不会触发重新渲染。适合用于不经常变化的静态内容。
3. React.memo
React.memo 是用于函数组件的高阶组件,类似于 PureComponent,可以帮助防止不必要的渲染。React.memo 通过浅比较来优化函数组件的性能:
const MyFunctionalComponent = React.memo(({ value }) => {return <div>{value}</div>;
});
使用 React.memo 包装后的组件,只有当 value 属性发生变化时才会重新渲染。如果有复杂的 props 检查逻辑,还可以自定义比较函数。
4. 避免使用内联函数
每次渲染时,内联函数会重新创建。可以将内联函数提取出来,减少函数的重新创建次数:
// 不推荐
<button onClick={() => console.log("clicked")}>Click</button>// 推荐
const handleClick = () => console.log("clicked");
<button onClick={handleClick}>Click</button>
提取函数可以减少内存消耗,尤其在组件内频繁传递回调函数的场景下,可以减少不必要的性能开销。
5. 使用 React.Fragment 避免额外标记
React.Fragment 可以用来避免额外的 DOM 元素包裹,减少不必要的 DOM 结构,提升性能:
// 不推荐
<div><h1>Title</h1><p>Content</p></div>// 推荐
<React.Fragment><h1>Title</h1><p>Content</p></React.Fragment>
或简写为 <></>。这不仅优化了 DOM 结构,也减少了浏览器的渲染时间。
6. 使用 Immutable.js 或 immer 进行不可变数据操作
React 依赖 props 和 state 的不可变性来判断是否需要重新渲染。使用 Immutable.js 或 immer 可以确保数据的不可变性:
import { Map } from 'immutable';const state = Map({ value: 1 });
const newState = state.set('value', 2); // 产生新的对象// 或者使用 immer
import produce from 'immer';const newState = produce(state, draft => {draft.value = 2;
});
这种方式可以优化性能,避免重复的对象引用,保证更新的数据结构具有新引用,触发 React 的重新渲染。
7. 懒加载组件
懒加载可以减少初始加载的资源占用,仅在需要时加载组件。可以通过 React.lazy 和 Suspense 实现组件的懒加载:
import React, { Suspense, lazy } from 'react';const LazyComponent = lazy(() => import('./LazyComponent'));function App() {return (<Suspense fallback={<div>Loading...</div>}><LazyComponent /></Suspense>);
}
懒加载特别适合于大型应用,减少首屏渲染时间,同时将不需要的代码分批加载。
React.Suspense使用介绍
React.Suspense 是 React 用于管理组件加载状态的一个功能,它通常与懒加载组件和数据请求一起使用,确保应用程序在加载数据或组件时提供用户友好的过渡体验。以下是 React.Suspense 的基础介绍及其常见用法。
1. 基本使用
React.Suspense 通过 fallback 属性来指定加载中的占位内容(如加载动画或文本),在懒加载组件或数据尚未加载完成时,显示该占位内容:
import React, { Suspense, lazy } from 'react';const LazyComponent = lazy(() => import('./LazyComponent'));function App() {return (<div><Suspense fallback={<div>Loading...</div>}><LazyComponent /></Suspense></div>);
}
在此示例中,LazyComponent 会在需要时才被加载,而不是在应用程序加载时就加载。当 LazyComponent 还没加载完成时,fallback 中的内容 <div>Loading...</div> 会显示在页面上。
2. 配合懒加载 (React.lazy)
React.lazy 可以实现组件的动态导入。配合 Suspense,可以实现按需加载,减少初始加载时间:
const LazyComponent = lazy(() => import('./LazyComponent'));
通过 lazy 将组件包装为懒加载模式,这样只有在组件被渲染时,LazyComponent 才会进行导入。
3. Suspense 与数据获取
自从 React 18 起,Suspense 也可以用来处理异步数据请求。在数据获取的场景下,可以与 React Server Components 或者像 React Query 这样的库结合使用。以下是一个简要示例:
import { Suspense } from 'react';function DataFetchingComponent() {const data = fetchData(); // 假设 fetchData 是一个获取数据的函数return <div>{data}</div>;
}function App() {return (<Suspense fallback={<div>Loading data...</div>}><DataFetchingComponent /></Suspense>);
}
在更复杂的应用中,可能会使用缓存库或 React 的新 useTransition 和 useDeferredValue 来进一步优化 Suspense 的效果和数据的呈现。
4. 多个 Suspense 组件
在复杂应用中,可能会嵌套或并列多个 Suspense 组件,以分阶段加载不同的部分。每个 Suspense 可以拥有不同的 fallback 内容,从而提供分区加载的用户体验:
function App() {return (<div><Suspense fallback={<div>Loading component A...</div>}><ComponentA /></Suspense><Suspense fallback={<div>Loading component B...</div>}><ComponentB /></Suspense></div>);
}
5. 注意事项
- Error Boundaries:
Suspense只能处理加载状态,但不处理错误。建议结合Error Boundaries来捕获和处理可能发生的错误。 - 支持环境:确保 React 版本支持
Suspense,特别是数据加载的Suspense需要React 18。
React.Suspense 的使用可以有效提高应用的响应速度和用户体验,特别是当组件和数据加载较多时。
8. 优化事件绑定方式
在组件上直接绑定事件会导致事件在每次渲染时都重新创建。可以通过在构造函数中绑定或使用 class fields 语法避免这个问题:
class MyComponent extends React.Component {constructor() {super();this.handleClick = this.handleClick.bind(this); // 在构造函数中绑定事件}handleClick() {console.log("clicked");}render() {return <button onClick={this.handleClick}>Click</button>;}
}
或者使用类字段语法:
class MyComponent extends React.Component {handleClick = () => {console.log("clicked");};render() {return <button onClick={this.handleClick}>Click</button>;}
}
这种方法减少了每次渲染时重新创建函数的性能开销。
9. 服务端渲染(Server-Side Rendering)
服务端渲染可以显著提高首屏渲染速度,尤其对 SEO 有较大帮助。使用 Next.js 等框架可以轻松实现 React 的服务端渲染:
// 使用 Next.js
import { useEffect } from 'react';function MyComponent({ data }) {return <div>{data}</div>;
}export async function getServerSideProps() {const data = await fetchData();return { props: { data } };
}export default MyComponent;
服务端渲染的页面在服务器上渲染成 HTML 返回客户端,客户端接收后进行静态内容显示并完成渲染后的数据填充,这样提高了用户的访问速度。
相关文章:
一七一、React性能优化方式
在 React 中进行性能优化可以通过多种手段来减少渲染次数、优化渲染效率并减少内存消耗。以下是常见的性能优化方法及示例: 1. shouldComponentUpdate shouldComponentUpdate 是类组件中的生命周期方法,它可以让组件在判断是否需要重新渲染时ÿ…...
编写dockerfile生成镜像,并且构建容器运行
编写dockerfile生成镜像,并且构建容器运行 目录 编写dockerfile生成镜像,并且构建容器运行 概述 一、dockerfile文件详解 Dockerfile的基本结构 Dockerfile的常用指令 二、构建过程 概述 随着微服务应用越来越多,大家需要尽快掌握dock…...
Java项目练习——学生管理系统
1. 整体结构 代码实现了基本的学生管理系统功能,包括登录、注册、忘记密码、添加、删除、修改和查询学生信息。 使用了ArrayList来存储用户和学生信息。 使用了Scanner类来处理用户输入。 2. 主要功能模块 登录 (logIn):验证用户名和密码,…...
sqlserver、达梦、mysql的差异
差异项sqlserver达梦mysql单行注释---- 1、-- ,--后面带个空格 2、# 包裹对象名称,如表、表字段等 [tableName] "tableName"tableName表字段自增IDENTITY(1, 1)IDENTITY(1, 1)AUTO_INCREMENT二进制数据类型IMAGEIMAGE、BLOBBLOB 存储一个汉字需…...
Spring AOP(定义、使用场景、用法、3种事务、事务失效场景及解决办法、面试题)
目录 1. AOP定义? 2.常见的AOP使用场景: 3.Spring AOP用法 3.1 Spring AOP中的几个核心概念 3.1.1 切面、切点、通知、连接点 3.1.2 切点表达式AspectJ 3.2 使用 Spring AOP 的步骤总结 3.2.1 添加依赖: 3.2.2 定义切面和切点(切点和…...
Flutter鸿蒙next 封装对话框详解
✅近期推荐:求职神器 https://bbs.csdn.net/topics/619384540 🔥欢迎大家订阅系列专栏:flutter_鸿蒙next 💬淼学派语录:只有不断的否认自己和肯定自己,才能走出弯曲不平的泥泞路,因为平坦的大路…...
【项目实战】通过LLaMaFactory+Qwen2-VL-2B微调一个多模态医疗大模型
前言 随着多模态大模型的发展,其不仅限于文字处理,更能够在图像、视频、音频方面进行识别与理解。医疗领域中,医生们往往需要对各种医学图像进行处理,以辅助诊断和治疗。如果将多模态大模型与图像诊断相结合,那么这会…...
SCSI驱动与 UFS 驱动交互概况
SCSI子系统概况 SCSI(Small Computer System Interface)子系统是 Linux 中的一个模块化框架,用于提供与存储设备的通用接口。通过 SCSI 子系统,可以支持不同类型的存储协议(如 UFS、SATA、SAS),…...
软件工程实践项目:人事管理系统
一、项目的需求说明 通过移动设备登录app提供简单、方便的操作。根据公司原来的考勤管理制度,为公司不同管理层次提供相应的权限功能。通过app上面的各种标准操作,考勤管理无纸化的实现,使公司的考勤管理更加科学规范,从而节省考…...
不使用三方软件,win系统下禁止单个应用联网能力的详细操作教程
本篇文章主要讲解,在win系统环境下,禁止某个应用联网能力的详细操作教程,通过本教程您可以快速掌握自定义对单个程序联网能力的限制和禁止。 作者:任聪聪 日期:2024年10月30日 步骤一、按下win按键(四个小方…...
近似线性可分支持向量机的原理推导
近似线性可分的意思是训练集中大部分实例点是线性可分的,只是一些特殊实例点的存在使得这种数据集不适用于直接使用线性可分支持向量机进行处理,但也没有到完全线性不可分的程度。所以近似线性可分支持向量机问题的关键就在于这些少数的特殊点。 相较于…...
Golang开发环境
Golang开发环境搭建 Go 语言开发包 国外:https://golang.org/dl/ 国内(推荐): https://golang.google.cn/dl/ 编辑器 Golang:https://www.jetbrains.com/go/ Visual Studio Code: https://code.visualstudio.com/ 搭建 Go 语言开发环境,需要…...
测试华为GaussDB(DWS)数仓,并通过APISQL快速将(表、视图、存储过程)发布为API
华为数据仓库服务 数据仓库服务(Data Warehouse Service,简称DWS)是一种基于公有云基础架构和平台的在线数据处理数据库,提供即开即用、可扩展且完全托管的分析型数据库服务。DWS是基于华为融合数据仓库GaussDB产品的云原生服务&a…...
使用GetX实现GetPage中间件
前言 GetX 中间件(Middleware)是 GetX 框架中的一种机制,用于在页面导航时对用户进行权限控制、数据预加载、页面访问条件设置等。通过使用中间件,可以有效地控制用户的访问流程,并在适当条件下引导用户到所需页面。 这…...
Navicat 17 功能简介 | SQL 预览
Navicat 17 功能简介 | SQL 预览 随着 17 版本的发布,Navicat 也带来了众多的新特性,包括兼容更多数据库、全新的模型设计、可视化智能 BI、智能数据分析、可视化查询解释、高质量数据字典、增强用户体验、扩展MongoDB 功能、轻松固定查询结果、便捷URI …...
ubuntu、Debian离线部署gitlab
一、软件包下载 gitlab安装包下载链接 ubuntu: ubuntu/focal 适用于 ubuntu20系列 ubuntu/bionic 适用于 ubuntu18 系列 Debian: debian/buster 适用于 Debian10系列 debian/bullseye 适用于 Debian11、12系列 二、安装gitlab ubuntu需要安装一些环境…...
数据库编程 SQLITE3 Linux环境
永久存储程序数据有两种方式: 用文件存储用数据库存储 对于多条记录的存储而言,采用文件时,插入、删除、查找的效率都会很差,为了提高这些操作的效率,有计算机科学家设计出了数据库存储方式 一、数据库 数据库的基本…...
独孤思维:总有一双眼睛默默观察你做副业
01 独孤昨天在陪伴群,分享了近期小白做副业的一些困扰。 并且以自己经历作为案例,分享了一些经验和方法。 最后顺势推出xx博主的关于365条赚钱信息小报童专栏。 订阅后,可以开拓副业赚钱思路,避免走一些弯路。 甚至于&#x…...
医院信息化与智能化系统(10)
医院信息化与智能化系统(10) 这里只描述对应过程,和可能遇到的问题及解决办法以及对应的参考链接,并不会直接每一步详细配置 如果你想通过文字描述或代码画流程图,可以试试PlantUML,告诉GPT你的文件结构,让他给你对应…...
基于YOLO11/v10/v8/v5深度学习的危险驾驶行为检测识别系统设计与实现【python源码+Pyqt5界面+数据集+训练代码】
《博主简介》 小伙伴们好,我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 ✌更多学习资源,可关注公-仲-hao:【阿旭算法与机器学习】,共同学习交流~ 👍感谢小伙伴们点赞、关注! 《------往期经典推…...
# 发散创新:边缘容器中的轻量级服务部署实战与优化策略在云计算向边缘计算演进的浪潮中,**边缘容器技术**正成
发散创新:边缘容器中的轻量级服务部署实战与优化策略 在云计算向边缘计算演进的浪潮中,边缘容器技术正成为构建低延迟、高可用应用的核心基础设施。相比传统云端Kubernetes集群,边缘容器更强调资源受限环境下的高效调度、快速启动和故障自愈能…...
MIB2 High Toolbox:重新定义车载娱乐系统定制体验
MIB2 High Toolbox:重新定义车载娱乐系统定制体验 【免费下载链接】mib2-toolbox The ultimate MIB2-HIGH toolbox. 项目地址: https://gitcode.com/gh_mirrors/mi/mib2-toolbox 车载娱乐系统是否还停留在出厂设置?想要个性化界面却苦于没有工具&…...
OpenGL之标准化设备坐标(Normalized Device Coordinate =NDC)
NDC坐标本质是比例1. 设备无关性NDC 使图形渲染与屏幕分辨率无关。无论屏幕是 1280720 还是 19201080,同样的 NDC 坐标都会渲染出相同比例的图形(图形会随着分辨率变化而自动拉伸),表现如下:┌────────────…...
OpenClaw技能扩展:安装百川2-13B-4bits专用插件提升自动化能力
OpenClaw技能扩展:安装百川2-13B-4bits专用插件提升自动化能力 1. 为什么需要为OpenClaw安装专用插件 去年冬天,我在处理一批技术文档归档任务时,发现OpenClaw的基础能力虽然强大,但在处理特定领域内容时总有些力不从心。比如让…...
利用快马ai快速生成流水线plc控制逻辑原型,无硬件也能验证思路
最近在做一个自动化流水线的小项目,需要设计PLC控制逻辑。传统方式需要先搭建硬件环境才能调试,但通过InsCode(快马)平台的AI辅助,我实现了无硬件环境下的快速原型验证,分享下这个实用经验。 项目背景与需求分析 这个流水线控制系…...
Homebrew卸载与重装指南:彻底清理残留文件的正确姿势
Homebrew深度清理与重装实战:从残留文件追踪到ARM架构优化 每次系统升级或开发环境切换时,那些隐藏在系统深处的Homebrew残留文件就像房间里扫不尽的灰尘——明明已经卸载了所有公式,却在重新安装时遇到各种诡异的权限错误或版本冲突。作为m…...
目标检测新手必看:如何用Python手写IOU计算函数(附完整代码)
目标检测实战:从零编写Python版IOU计算函数 刚接触目标检测时,最让人困惑的莫过于那些神秘的评估指标。其中IOU(交并比)就像一把尺子,能量化算法预测框与真实框的贴合程度。但纸上得来终觉浅,今天我们就用P…...
ENVI 5.3波谱库实战:从自带库浏览到自定义库创建,遥感地物识别效率翻倍
ENVI 5.3波谱库实战:从自带库浏览到自定义库创建,遥感地物识别效率翻倍 在遥感图像解译工作中,地物波谱特征就像每类物质的"光学指纹"。ENVI 5.3的波谱库功能,正是帮助我们从海量遥感数据中快速匹配这些"指纹"…...
AI首推路径控制引擎
AI首推路径控制引擎版本:v2.0.0 发布日期:2026年3月26日 发布状态:正式全量发布---一、背景与概述在AI生成式应用中,模型输出的随机性与不可控性一直是业务落地的核心痛点。为解决“如何让AI严格遵循预设逻辑生成答案”的问题&…...
GLM-OCR模型安装包制作:将模型与服务打包成可执行文件
GLM-OCR模型安装包制作:将模型与服务打包成可执行文件 你是不是也遇到过这样的情况?自己好不容易把一个AI模型跑起来了,效果也不错,想分享给同事或者朋友用用,结果对方光是配环境、装依赖就折腾了半天,最后…...
