一七一、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 返回客户端,客户端接收后进行静态内容显示并完成渲染后的数据填充,这样提高了用户的访问速度。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/460611.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

docker-minio启动参数

完整命令 docker run -p 9000:9000 -p 9090:9090 -v /opt/minio/data:/data -d --name minio -d --restartalways -e "MINIO_ACCESS_KEYminio" -e "MINIO_SECRET_KEYminioadmin123" minio/minio server --console-address ":9090" -address &…

理解 CSS 中的绝对定位与 Flex 布局混用

理解 CSS 中的绝对定位与 Flex 布局混用 在现代网页设计中&#xff0c;CSS 布局技术如 flex 和绝对定位被广泛使用。然而&#xff0c;这两者结合使用时&#xff0c;可能会导致一些意想不到的布局问题。本文将探讨如何正确使用绝对定位元素&#xff0c;避免它们受到 flex 布局的…

书生大模型实战营 L0 入门岛

书生大模型训练营入门岛任务——训练营链接 1. Linux前置知识 任务&#xff1a;端口转发 当使用vscode远程连接服务器时&#xff0c;在服务器运行的任务&#xff0c;vscode会自动帮忙进行端口映射&#xff0c;方便本地进行访问。 2. Python前置知识 任务1&#xff1a;Leec…

网络搜索引擎Shodan(2)

声明&#xff1a;学习视频来自b站up主 泷羽sec&#xff0c;如涉及侵权马上删除文章 声明&#xff1a;本文主要用作技术分享&#xff0c;所有内容仅供参考。任何使用或依赖于本文信息所造成的法律后果均与本人无关。请读者自行判断风险&#xff0c;并遵循相关法律法规。 感谢泷…

Linux 练习三

1、建立用户组 shengcan&#xff0c;其id 为 2000 [rootlocalhost 桌面]# groupadd -g 2000 shengchan 2、建立用户组 caiwu&#xff0c;其id 为 2001 [rootlocalhost 桌面]# groupadd -g 2001 caiwu 3、建立用户组 jishu&#xff0c;其 id 为 2002 [rootlocalhost 桌面]#…

Docker Compose一键部署Spring Boot + Vue项目

目录 前提条件 概述 Compose简介 Compose文件 Compose环境 Compose命令 帮助命令 关键命令 Compose部署项目 初始化环境 查看代码文件 sql数据准备 nginx配置文件准备 创建 compose.yaml 一键启动compose多个容器 浏览器访问虚拟机ip:80(可省略默认的80端口) …

C语言 | Leetcode C语言题解之第522题最长特殊序列II

题目&#xff1a; 题解&#xff1a; #define MAX(a, b) ((a) > (b) ? (a) : (b))bool is_subseq(const char *s, const char *t) {int pt_s 0, pt_t 0;int len_s strlen(s), len_t strlen(t);while (pt_s < len_s && pt_t < len_t) {if (s[pt_s] t[pt_…

第二十三章 Vue组件通信之非父子组件通信

目录 一、引言 1.1. event bus 事件总线 1.1.1. 实现步骤 1.2. provide & inject 1.2.1. 实现步骤 二、event bus事件总线完整代码 2.1. 工程结构图 ​2.2. main.js 2.3. App.vue 2.4. EventBus.js 2.5. BaseC.vue 2.6. BaseB.vue 2.7. BaseA.vue 三、provi…

无人机之自动控制原理篇

一、飞控系统 无人机飞控是指无人机的飞行控制系统&#xff0c;是无人机的大脑。飞控系统通过传感器、控制器和执行机构三部分实现对无人机的自动控制。 传感器&#xff1a;传感器负责收集无人机的姿态、速度、高度等信息。常见的传感器包括陀螺仪、加速度计、磁力计、气压计、…

JS实现图片放大镜效果

代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title><styl…

链表:两数相加

目录 LeetCode2 两数相加 LeetCode445 两数相加II LeetCode2 两数相加 /*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode() : val(0), next(nullptr) {}* ListNode(int x) : val(x), next(nullptr) {}* …

练习LabVIEW第二十九题

学习目标&#xff1a; 刚学了LabVIEW&#xff0c;在网上找了些题&#xff0c;练习一下LabVIEW&#xff0c;有不对不好不足的地方欢迎指正&#xff01; 第二十九题&#xff1a; 设计一评分程序&#xff0c;输入不同的分数会得到不同的评论。 分数小于60&#xff0c;“警告”指…

Unity3D 开发教程:从入门到精通

Unity3D 开发教程&#xff1a;从入门到精通 Unity3D 是一款强大的跨平台游戏引擎&#xff0c;广泛应用于游戏开发、虚拟现实、增强现实等领域。本文将详细介绍 Unity3D 的基本概念、开发流程以及一些高级技巧&#xff0c;帮助你从零基础到掌握 Unity3D 开发。 目录 Unity3D…

3.2 大数据概念、特征与价值

文章目录 大数据的概念美国高德纳咨询公司的定义麦肯锡全球研究所的定义狭义和广义的大数据 大数据的特征Volume&#xff08;体积&#xff09;Variety&#xff08;种类&#xff09;Velocity&#xff08;速度&#xff09;Value&#xff08;价值&#xff09;Veracity&#xff08;…

扫雷游戏(C语言详解)

扫雷游戏&#xff08;C语言详解&#xff09; 放在最前面的1、前言&#xff08;扫雷游戏的简介&#xff09;2、扫雷游戏的规则&#xff08;简易版&#xff09;3、代码实现&#xff08;3.1&#xff09;提醒一下&#xff1a;( i ) 提醒1&#xff1a;( ii ) 提醒2&#xff1a; &…

WPF+MVVM案例实战(十四)- 封装一个自定义消息弹窗控件(下)

文章目录 1、案例效果2、弹窗空间使用1.引入用户控件2、按钮命令实现 3、总结4、源代码获取 1、案例效果 2、弹窗空间使用 1.引入用户控件 打开 Wpf_Examples 项目&#xff0c;在引用中添加用户控件库&#xff0c;在 MainWindow.xaml 界面引用控件库&#xff0c;代码如下&…

银河麒麟v10 xrdp安装

为了解决科技被卡脖子的问题&#xff0c;国家正在大力推进软硬件系统的信创替代&#xff0c;对于一些平时对Linux操作系统不太熟练的用户来讲提出了更高的挑战和要求。本文以银河麒麟v10 24.03为例带领大家配置kylin v10的远程桌面。 最近公司为了配置信创开发新购了几台银河麒…

Python小游戏17——飞机大战

运行结果 首先&#xff0c;你需要安装Pygame库。如果你还没有安装它&#xff0c;可以使用以下命令来安装&#xff1a; bash pip install pygame 代码&#xff1a; python import pygame import random # 初始化Pygame pygame.init() # 屏幕大小 SCREEN_WIDTH 800 SCREEN_HEIGH…

国标GB28181软件EasyGBS国标GB28181网页直播平台在邮政快递场景中的应用

随着电子商务的迅猛发展&#xff0c;邮政快递行业迎来了前所未有的发展机遇&#xff0c;但同时也面临着诸多挑战。如何在保障货物安全、提高运输效率的同时&#xff0c;实现全面的监控和管理&#xff0c;成为邮政快递企业亟需解决的问题。国标GB28181网页直播平台EasyGBS作为一…

MFC工控项目实例二十七添加产品参数

承接专栏《MFC工控项目实例二十六创建数据库》 在型号参数界面添加三个参数试验时间、最小值、最大值。变量为double m_edit_time; double m_edit_min; double m_edit_max; 1、在SEAL_PRESSURE.h中添加代码 class CProductPara { public:union{struct{...double m_edit_min;…