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

一七一、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>;}
}

在这个示例中,组件只有在 valuecount 发生变化时才会重新渲染,这样可以避免不必要的渲染,提高性能。

2. PureComponent

PureComponent 是类组件的替代方案,使用浅层比较 propsstate 来确定是否重新渲染。它相当于内置了 shouldComponentUpdate 的优化:

import React, { PureComponent } from 'react';class MyPureComponent extends PureComponent {render() {return <div>{this.props.value}</div>;}
}

PureComponent 自动实现了浅比较(shallow comparison),如果 propsstate 没有变化,就不会触发重新渲染。适合用于不经常变化的静态内容。

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.jsimmer 进行不可变数据操作

React 依赖 propsstate 的不可变性来判断是否需要重新渲染。使用 Immutable.jsimmer 可以确保数据的不可变性:

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.lazySuspense 实现组件的懒加载:

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 的新 useTransitionuseDeferredValue 来进一步优化 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 BoundariesSuspense 只能处理加载状态,但不处理错误。建议结合 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 中进行性能优化可以通过多种手段来减少渲染次数、优化渲染效率并减少内存消耗。以下是常见的性能优化方法及示例&#xff1a; 1. shouldComponentUpdate shouldComponentUpdate 是类组件中的生命周期方法&#xff0c;它可以让组件在判断是否需要重新渲染时&#xff…...

编写dockerfile生成镜像,并且构建容器运行

编写dockerfile生成镜像&#xff0c;并且构建容器运行 目录 编写dockerfile生成镜像&#xff0c;并且构建容器运行 概述 一、dockerfile文件详解 Dockerfile的基本结构 Dockerfile的常用指令 二、构建过程 概述 随着微服务应用越来越多&#xff0c;大家需要尽快掌握dock…...

Java项目练习——学生管理系统

1. 整体结构 代码实现了基本的学生管理系统功能&#xff0c;包括登录、注册、忘记密码、添加、删除、修改和查询学生信息。 使用了ArrayList来存储用户和学生信息。 使用了Scanner类来处理用户输入。 2. 主要功能模块 登录 (logIn)&#xff1a;验证用户名和密码&#xff0c;…...

sqlserver、达梦、mysql的差异

差异项sqlserver达梦mysql单行注释---- 1、-- &#xff0c;--后面带个空格 2、# 包裹对象名称&#xff0c;如表、表字段等 [tableName] "tableName"tableName表字段自增IDENTITY(1, 1)IDENTITY(1, 1)AUTO_INCREMENT二进制数据类型IMAGEIMAGE、BLOBBLOB 存储一个汉字需…...

Spring AOP(定义、使用场景、用法、3种事务、事务失效场景及解决办法、面试题)

目录 1. AOP定义&#xff1f; 2.常见的AOP使用场景&#xff1a; 3.Spring AOP用法 3.1 Spring AOP中的几个核心概念 3.1.1 切面、切点、通知、连接点 3.1.2 切点表达式AspectJ 3.2 使用 Spring AOP 的步骤总结 3.2.1 添加依赖: 3.2.2 定义切面和切点&#xff08;切点和…...

Flutter鸿蒙next 封装对话框详解

✅近期推荐&#xff1a;求职神器 https://bbs.csdn.net/topics/619384540 &#x1f525;欢迎大家订阅系列专栏&#xff1a;flutter_鸿蒙next &#x1f4ac;淼学派语录&#xff1a;只有不断的否认自己和肯定自己&#xff0c;才能走出弯曲不平的泥泞路&#xff0c;因为平坦的大路…...

【项目实战】通过LLaMaFactory+Qwen2-VL-2B微调一个多模态医疗大模型

前言 随着多模态大模型的发展&#xff0c;其不仅限于文字处理&#xff0c;更能够在图像、视频、音频方面进行识别与理解。医疗领域中&#xff0c;医生们往往需要对各种医学图像进行处理&#xff0c;以辅助诊断和治疗。如果将多模态大模型与图像诊断相结合&#xff0c;那么这会…...

SCSI驱动与 UFS 驱动交互概况

SCSI子系统概况 SCSI&#xff08;Small Computer System Interface&#xff09;子系统是 Linux 中的一个模块化框架&#xff0c;用于提供与存储设备的通用接口。通过 SCSI 子系统&#xff0c;可以支持不同类型的存储协议&#xff08;如 UFS、SATA、SAS&#xff09;&#xff0c…...

软件工程实践项目:人事管理系统

一、项目的需求说明 通过移动设备登录app提供简单、方便的操作。根据公司原来的考勤管理制度&#xff0c;为公司不同管理层次提供相应的权限功能。通过app上面的各种标准操作&#xff0c;考勤管理无纸化的实现&#xff0c;使公司的考勤管理更加科学规范&#xff0c;从而节省考…...

不使用三方软件,win系统下禁止单个应用联网能力的详细操作教程

本篇文章主要讲解&#xff0c;在win系统环境下&#xff0c;禁止某个应用联网能力的详细操作教程&#xff0c;通过本教程您可以快速掌握自定义对单个程序联网能力的限制和禁止。 作者&#xff1a;任聪聪 日期&#xff1a;2024年10月30日 步骤一、按下win按键&#xff08;四个小方…...

近似线性可分支持向量机的原理推导

近似线性可分的意思是训练集中大部分实例点是线性可分的&#xff0c;只是一些特殊实例点的存在使得这种数据集不适用于直接使用线性可分支持向量机进行处理&#xff0c;但也没有到完全线性不可分的程度。所以近似线性可分支持向量机问题的关键就在于这些少数的特殊点。 相较于…...

Golang开发环境

Golang开发环境搭建 Go 语言开发包 国外&#xff1a;https://golang.org/dl/ 国内(推荐)&#xff1a; https://golang.google.cn/dl/ 编辑器 Golang:https://www.jetbrains.com/go/ Visual Studio Code: https://code.visualstudio.com/ 搭建 Go 语言开发环境&#xff0c;需要…...

测试华为GaussDB(DWS)数仓,并通过APISQL快速将(表、视图、存储过程)发布为API

华为数据仓库服务 数据仓库服务&#xff08;Data Warehouse Service&#xff0c;简称DWS&#xff09;是一种基于公有云基础架构和平台的在线数据处理数据库&#xff0c;提供即开即用、可扩展且完全托管的分析型数据库服务。DWS是基于华为融合数据仓库GaussDB产品的云原生服务&a…...

使用GetX实现GetPage中间件

前言 GetX 中间件&#xff08;Middleware&#xff09;是 GetX 框架中的一种机制&#xff0c;用于在页面导航时对用户进行权限控制、数据预加载、页面访问条件设置等。通过使用中间件&#xff0c;可以有效地控制用户的访问流程&#xff0c;并在适当条件下引导用户到所需页面。 这…...

Navicat 17 功能简介 | SQL 预览

Navicat 17 功能简介 | SQL 预览 随着 17 版本的发布&#xff0c;Navicat 也带来了众多的新特性&#xff0c;包括兼容更多数据库、全新的模型设计、可视化智能 BI、智能数据分析、可视化查询解释、高质量数据字典、增强用户体验、扩展MongoDB 功能、轻松固定查询结果、便捷URI …...

ubuntu、Debian离线部署gitlab

一、软件包下载 gitlab安装包下载链接 ubuntu&#xff1a; ubuntu/focal 适用于 ubuntu20系列 ubuntu/bionic 适用于 ubuntu18 系列 Debian&#xff1a; debian/buster 适用于 Debian10系列 debian/bullseye 适用于 Debian11、12系列 二、安装gitlab ubuntu需要安装一些环境…...

数据库编程 SQLITE3 Linux环境

永久存储程序数据有两种方式&#xff1a; 用文件存储用数据库存储 对于多条记录的存储而言&#xff0c;采用文件时&#xff0c;插入、删除、查找的效率都会很差&#xff0c;为了提高这些操作的效率&#xff0c;有计算机科学家设计出了数据库存储方式 一、数据库 数据库的基本…...

独孤思维:总有一双眼睛默默观察你做副业

01 独孤昨天在陪伴群&#xff0c;分享了近期小白做副业的一些困扰。 并且以自己经历作为案例&#xff0c;分享了一些经验和方法。 最后顺势推出xx博主的关于365条赚钱信息小报童专栏。 订阅后&#xff0c;可以开拓副业赚钱思路&#xff0c;避免走一些弯路。 甚至于&#x…...

医院信息化与智能化系统(10)

医院信息化与智能化系统(10) 这里只描述对应过程&#xff0c;和可能遇到的问题及解决办法以及对应的参考链接&#xff0c;并不会直接每一步详细配置 如果你想通过文字描述或代码画流程图&#xff0c;可以试试PlantUML&#xff0c;告诉GPT你的文件结构&#xff0c;让他给你对应…...

基于YOLO11/v10/v8/v5深度学习的危险驾驶行为检测识别系统设计与实现【python源码+Pyqt5界面+数据集+训练代码】

《博主简介》 小伙伴们好&#xff0c;我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 ✌更多学习资源&#xff0c;可关注公-仲-hao:【阿旭算法与机器学习】&#xff0c;共同学习交流~ &#x1f44d;感谢小伙伴们点赞、关注&#xff01; 《------往期经典推…...

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...

相机Camera日志实例分析之二:相机Camx【专业模式开启直方图拍照】单帧流程日志详解

【关注我&#xff0c;后续持续新增专题博文&#xff0c;谢谢&#xff01;&#xff01;&#xff01;】 上一篇我们讲了&#xff1a; 这一篇我们开始讲&#xff1a; 目录 一、场景操作步骤 二、日志基础关键字分级如下 三、场景日志如下&#xff1a; 一、场景操作步骤 操作步…...

STM32标准库-DMA直接存储器存取

文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA&#xff08;Direct Memory Access&#xff09;直接存储器存取 DMA可以提供外设…...

postgresql|数据库|只读用户的创建和删除(备忘)

CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...

什么是EULA和DPA

文章目录 EULA&#xff08;End User License Agreement&#xff09;DPA&#xff08;Data Protection Agreement&#xff09;一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA&#xff08;End User License Agreement&#xff09; 定义&#xff1a; EULA即…...

Axios请求超时重发机制

Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式&#xff1a; 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...

Mysql中select查询语句的执行过程

目录 1、介绍 1.1、组件介绍 1.2、Sql执行顺序 2、执行流程 2.1. 连接与认证 2.2. 查询缓存 2.3. 语法解析&#xff08;Parser&#xff09; 2.4、执行sql 1. 预处理&#xff08;Preprocessor&#xff09; 2. 查询优化器&#xff08;Optimizer&#xff09; 3. 执行器…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...

在 Spring Boot 项目里,MYSQL中json类型字段使用

前言&#xff1a; 因为程序特殊需求导致&#xff0c;需要mysql数据库存储json类型数据&#xff0c;因此记录一下使用流程 1.java实体中新增字段 private List<User> users 2.增加mybatis-plus注解 TableField(typeHandler FastjsonTypeHandler.class) private Lis…...

字符串哈希+KMP

P10468 兔子与兔子 #include<bits/stdc.h> using namespace std; typedef unsigned long long ull; const int N 1000010; ull a[N], pw[N]; int n; ull gethash(int l, int r){return a[r] - a[l - 1] * pw[r - l 1]; } signed main(){ios::sync_with_stdio(false), …...