[React] 性能优化相关 (二)

文章目录

      • 1.避免使用内联对象
      • 2.避免使用匿名函数
      • 3.延迟加载不是立即需要的组件
      • 4.调整CSS而不是强制组件加载和卸载
      • 5.使用React.Fragment避免添加额外的DOM
      • 6.使用React.PureComponent , shouldComponentUpdate

1.避免使用内联对象

使用内联对象时,react会在每次渲染时重新创建对此对象的引用,这会导致接收此对象的组件将其视为不同的对象。因此,该组件对于props的千层比较始终返回false,导致组件一直渲染。

// Don't do this!
function Component(props) {const aProp = { someProp: 'someValue' }return <AComponent style={{ margin: 0 }} aProp={aProp} />  
}// Do this instead :)
const styles = { margin: 0 };
function Component(props) {const aProp = { someProp: 'someValue' }return <AComponent style={styles} {...aProp} />  
}

2.避免使用匿名函数

虽然匿名函数是传递函数的好方法,但它们在每次渲染上都有不同的引用。类似于内联对象。

为了保证作为props传递给react组件的函数的相同引用,如果使用的类组件可以将其声明为类方法,如果使用的函数组件,可以使用useCallback钩子来保持相同的引用。

// 避免这样做
function Component(props) {return <AComponent onChange={() => props.callback(props.id)} />  
}// 函数组件,优化方法一
function Component(props) {const handleChange = useCallback(() => props.callback(props.id), [props.id]);return <AComponent onChange={handleChange} />  
}// 类组件,优化方法二
class Component extends React.Component {handleChange = () => {this.props.callback(this.props.id) }render() {return <AComponent onChange={this.handleChange} />}
}

3.延迟加载不是立即需要的组件

React.lazy和React.Suspense完成延迟加载不是立即需要的组件。React加载的组件越少,加载组件的速度越快。

// React.lazy 接受一个函数,这个函数需要动态调用 import()引入组件
const HomeIndex = React.lazy(() => import('@/modules/home'))
......// 然后应在 Suspense 组件中渲染 lazy 组件,如此使得我们可以使用在等待加载 lazy 组件时做优雅降级(如 loading 指示器等)
return(<React.Suspense fallback={<>Loading...</>}><HomeIndex /></React.Suspense>
)// 一般会封装一个公共的方法
const withLoadingComponent = (comp: JSX.Element) => (<React.Suspense fallback={<>Loading...</>}>{comp}</React.Suspense>
)// 调用方法,传入要延迟加载的组件
return({withLoadingComponent(<HomeIndex />}
)

4.调整CSS而不是强制组件加载和卸载

有时保持组件加载的同时,通过CSS隐藏可能是有益的,而不是通过卸载来隐藏。对于具有显著的加载或卸载时序的重型组件而言,这是有效的性能优化手段。

将元素透明度调整为0对浏览器的成本消耗几乎为0(因为它不会导致重排),并且应该尽可能优先更改visibility或display。

// 避免对大型的组件频繁对加载和卸载
function Component(props) {const [view, setView] = useState('view1');return view === 'view1' ? <AComponent /> : <BComponent />  
}// 使用该方式提升性能和速度
const visibleStyles = { opacity: 1 };
const hiddenStyles = { opacity: 0 };
function Component(props) {const [view, setView] = useState('view1');return (<React.Fragment><AComponent style={view === 'view1' ? visibleStyles : hiddenStyles}><BComponent style={view !== 'view1' ? hiddenStyles : visibleStyles}></React.Fragment>)
}

5.使用React.Fragment避免添加额外的DOM

有些情况下,我们需要在组件中返回多个元素,例如下面的元素,但是在react规定组件中必须有一个父元素。

	<h1>Hello world!</h1><h1>Hello there!</h1><h1>Hello there again!</h1>

为了减少不必要的加载时间,我们可以使React.Fragment来避免创建不必要的元素。

function Component() {return (<React.Fragment><h1>Hello world!</h1><h1>Hello there!</h1><h1>Hello there again!</h1></React.Fragment>)
}

6.使用React.PureComponent , shouldComponentUpdate

父组件状态的每次更新,都会导致子组件的重新渲染,即使是传入相同props。但是这里的重新渲染不是说会更新DOM,而是每次都会调用diif算法来判断是否需要更新DOM。这对于大型组件例如组件树来说是非常消耗性能的。

在这里我们就可以使用React.PureComponent , shouldComponentUpdate生命周期来确保只有当组件props状态改变时才会重新渲染。

import React, { Component, PureComponent } from "react";// 没有变化不会触发render, 有变化触发render: 
// 组件优化: 1.只要执行了setState, 都会触发render 2.触发render, 会render组件
// 只有当前state和props数据发生改变的话才触发render
// shouldComponentUpdate() 返回为 true
export default class Parent extends Component {state = { count: 0 };// 重写 shouldComponentUpdate()shouldComponentUpdate(nextProps, nextState){if(this.state.count === nextState.count) return falseelse return true}// 如果修改的对象和以前的对象有一点联系的话, 不会触发render, 比如就修改对象的名称, 不修改对象的地址render() {const { count } = this.state;return (<div className="parent">Parent<br />{count}<button onClick={() => this.setState({ count: 1 })}>1</button><Chird count={count} /></div>);}
}class Chird extends PureComponent {// shouldComponentUpdate(nextProps, nextState){//   return !this.props.count === nextProps.count// }render() {return (<div className="child">Chird<br />{this.props.count}</div>);}
}

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

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

相关文章

条件查询和数据查询

一、后端 1.controller层 package com.like.controller;import com.like.common.CommonDto; import com.like.entity.User; import com.like.service.UserService; import jakarta.annotation.Resource; import org.springframework.web.bind.annotation.GetMapping; import …

C语言 —— 函数

目录 1. 函数是什么 2. C语言中函数的分类 2.1 库函数 2.2 自定义函数 3. 函数的参数 3.1 实际参数(实参) 3.2 形式参数(形参) 4. 函数的调用 4.1 传值调用 4.2 传址调用 5. 函数的嵌套调用和链式访问 5.1 嵌套调用 5.2 链式访问 6. 函数的声明和定义 6.1函数声明…

24Hibench

1. Hibench 官网 ​ HiBench is a big data benchmark suite that helps evaluate different big data frameworks in terms of speed, throughput and system resource utilizations. It contains a set of Hadoop, Spark and streaming workloads, including Sort, WordCou…

JavaSE | 初始Java(九) | 包的使用

包 包是对类、接口等的封装机制的体现&#xff0c;是一种对类或者接口等的很好的组织方式&#xff0c;比如&#xff1a;一个包中的类不想被其他包中的类使用。包还有一个重要的作用&#xff1a;在同一个工程中允许存在相同名称的类&#xff0c;只要处在不同的包中即可。 可以…

软断言你也学不会

断言是测试用例的一部分&#xff0c;也是测试工程师开发测试用例的核心。断言通常集成在单元测试和集成测试中&#xff0c;断言分为硬断言和软断言。 硬断言是我们狭义上听到的普通断言:当用例运行后得到的[实际]结果与预期结果不匹配时&#xff0c;测试框架将停止测试执行并抛…

Python实时采集Windows CPU\MEMORY\HDD使用率

文章目录 安装psutil库在Python脚本中导入psutil库获取CPU当前使用率&#xff0c;并打印结果获取内存当前使用率&#xff0c;并打印结果获取磁盘当前使用情况&#xff0c;并打印结果推荐阅读 要通过Python实时采集Windows性能计数器的数据&#xff0c;你可以使用psutil库。psut…

AutoCAD 产品设计:图形单位

本文讲解 AutoCAD 产品的图形单位功能产品设计&#xff0c;没有任何代码实现。 使用的 AutoCAD 为 2020 版本 图形单位是什么&#xff1f; 图形单位是用于设置 一些属性数据应该用什么格式显示 的命令&#xff0c;命令标识为 un&#xff08;units&#xff09;。 举个例子。 …

WebGL笔记:绘制多个点,三角形,以及画各种不同的线条,面

绘制多点 1 &#xff09; WebGL 缓冲区 我们在用js定点位的时候&#xff0c;肯定是要建立一份顶点数据的&#xff0c;这份顶点数据是给着色器的&#xff0c;因为着色器需要这份顶点数据绘图然而&#xff0c;我们在js中建立顶点数据&#xff0c;着色器肯定是拿不到的&#xff…

基于SpringBoot的反诈宣传平台设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09;有保障的售后福利 代码参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作…

问 ChatGPT 关于GPT的事情:扩展篇

一、GPT预训练有什么节省显存和算力的技巧吗&#xff1f;我如何拿四块A100完成175B模型的预训练&#xff1f; 对于GPT预训练&#xff0c;有一些技巧可以帮助节省显存和算力。以下是一些常用的技巧&#xff1a; 按批次截断&#xff1a;在较长的文本序列中&#xff0c;将其切割…

SpringBoot注册web组件

目录 前言 一、注册Servlet组件 1.1 使用SpringBoot注解加继承HttpServet类注册 1.2 通过继承HttpServet类加配置类来进行注册 二、注册Listener组件 2.1 使用SpringBoot注解和实现ServletContextListener接口注册 2.2 ServletContextListener接口和配置类来进行注册 …

【Spring】Spring 创建和使用

Spring 创建和使用 一. 创建 Spring 项目1. 创建⼀个 Maven 项目2. 添加 Spring 框架⽀持3. 添加启动类 二. 存储 Bean 对象1. 创建 Bean2. 将 Bean 注册到容器 三. 获取并使⽤ Bean 对象1. 创建 Spring 上下文2. 获取指定的 Bean 对象3. 使用 Bean Spring 就是⼀个包含了众多⼯…

函数

章节目录&#xff1a; 一、定义一个函数1.1 相关概述1.2 句式规则 二、参数传递2.1 变量类型2.2 可变与不可变2.3 传不可变对象实例2.4 传可变对象实例 三、参数3.1 必需参数3.2 关键字参数3.3 默认参数3.4 不定长参数 四、匿名函数五、强制位置参数六、结束语 一、定义一个函数…

【vue3】wacth监听,监听ref定义的数据,监听reactive定义的数据,详解踩坑点

假期第二篇&#xff0c;对于基础的知识点&#xff0c;我感觉自己还是很薄弱的。 趁着假期&#xff0c;再去复习一遍 之前已经记录了一篇【vue3基础知识点-computed和watch】 今天在学习的过程中发现&#xff0c;之前记录的这一篇果然是很基础的&#xff0c;很多东西都讲的不够…

python复习

1.python属于解释型语言&#xff0c;解释器逐行解释每一句代码&#xff0c;然后执行 编译型语言需要由编译器生成最终可执行文件再执行 2. #单行注释""" 多行注释 """ 注释快捷键ctrl/ 3.变量是在计算机语言中能储存计算结果或表示某个数据…

Docker介绍与安装

目录 一、Docker 概述 1、什么时Docker 2、Docker的设计宗旨 4、Docker的优点 5、Docker容器和虚拟机的区别 6、 namespace的隔离&#xff08;命名空间&#xff09; 7、 Docker的三个核心概念 7.1 镜像 7.2 容器 7.3 仓库&#xff08;Docker Hapu&#xff09; 二、D…

Sentinel-2波段合成

Sentinel-2波段合成 在上一篇博客中下载了Sentinel-2数据&#xff0c;他有13个波段的.jp2文件&#xff0c;下面选取需要使用的波段进行合成。 导入了B2&#xff08;蓝色&#xff09;、B3&#xff08;绿色&#xff09;、B4&#xff08;红色&#xff09;、B8&#xff08;近红外&…

php实战案例记录(9)一行循环不使用花括号的写法

在 PHP 中&#xff0c;你可以将 foreach 循环写成一行&#xff0c;而不使用花括号 {}。这被称为“一行循环”&#xff08;Inline Loop&#xff09;。 下面是将 foreach ($_GET as $key > $value) 写成一行循环的示例&#xff1a; foreach ($_GET as $key > $value) ech…

Ubuntu下文件的解压缩操作:常用zip和unzip

Ubuntu下文件的解\压缩 压缩一个文件夹为zip包&#xff0c;加参数-r&#xff1a; zip -r MyWeb.zip MyWeb需要排除目录里某个文件夹&#xff1f;例如我要去掉node_modules&#xff0c;以显著减小压缩包体积&#xff0c;此时该怎么做&#xff1f; zip -r MyWeb.zip ./MyWeb…

Linux--网络编程-字节序

进程间的通信&#xff1a; 管道、消息队列、共享内存、信号、信号量。 特点&#xff1a;都依赖于linux内核。 缺陷&#xff1a;无法多机通信。 一、网络编程&#xff1a; 1、地址&#xff1a;基于网络&#xff0c;ip地址端口号。 端口号作用&#xff1a; 一台拥有ip地址的主机…