React-性能优化的手段

server/2024/9/22 19:19:23/

b15c93b7b73c4ec6b712ebea1fcd685f.png

​🌈个人主页:前端青山
🔥系列专栏:React篇
🔖人终将被年少不可得之物困其一生

依旧青山,本期给大家带来React篇专栏内容:React-性能优化的手段

目录

 React 性能优化的手段有哪些?

一、是什么

二、如何做

避免使用内联函数

使用 React Fragments 避免额外标记

事件绑定方式

使用 Immutable

懒加载组件

服务端渲染

其他

 React 性能优化的手段有哪些?

 

e7f1dbaae501cfba321d11b0b9f444e5.png

一、是什么

React凭借virtual DOMdiff算法拥有高效的性能,但是某些情况下,性能明显可以进一步提高

在前面文章中,我们了解到类组件通过调用setState方法, 就会导致render,父组件一旦发生render渲染,子组件一定也会执行render渲染

当我们想要更新一个子组件的时候,如下图绿色部分:

 

6fb2ef1ba05030cecb0da6d6f53b0e46.png

理想状态只调用该路径下的组件render

 

920dc68f5bea2e7473107dba7569594f.png

但是react的默认做法是调用所有组件的render,再对生成的虚拟DOM进行对比(黄色部分),如不变则不进行更新

 

5bf55726bb9906e1c8b0293ffe13bbf8.png

从上图可见,黄色部分diff算法对比是明显的性能浪费的情况

 

 

二、如何做

在React中如何避免不必要的render中,我们了解到如何避免不必要的render来应付上面的问题,主要手段是通过shouldComponentUpdatePureComponentReact.memo,这三种形式这里就不再复述

除此之外, 常见性能优化常见的手段有如下:

  • 避免使用内联函数

  • 使用 React Fragments 避免额外标记

  • 使用 Immutable

  • 懒加载组件

  • 事件绑定方式

  • 服务端渲染

避免使用内联函数

如果我们使用内联函数,则每次调用render函数时都会创建一个新的函数实例,如下:

javascript">import React from "react";
​
export default class InlineFunctionComponent extends React.Component {render() {return (<div><h1>Welcome Guest</h1><input type="button" onClick={(e) => { this.setState({inputValue: e.target.value}) }} value="Click For Inline Function" /></div>)}
}

我们应该在组件内部创建一个函数,并将事件绑定到该函数本身。这样每次调用 render 时就不会创建单独的函数实例,如下:

javascript">import React from "react";
​
export default class InlineFunctionComponent extends React.Component {setNewStateData = (event) => {this.setState({inputValue: e.target.value})}render() {return (<div><h1>Welcome Guest</h1><input type="button" onClick={this.setNewStateData} value="Click For Inline Function" /></div>)}
}

使用 React Fragments 避免额外标记

用户创建新组件时,每个组件应具有单个父标签。父级不能有两个标签,所以顶部要有一个公共标签,所以我们经常在组件顶部添加额外标签div

这个额外标签除了充当父标签之外,并没有其他作用,这时候则可以使用fragement

其不会向组件引入任何额外标记,但它可以作为父级标签的作用,如下所示:

javascript">export default class NestedRoutingComponent extends React.Component {render() {return (<><h1>This is the Header Component</h1><h2>Welcome To Demo Page</h2></>)}
}

 

事件绑定方式

在事件绑定方式中,我们了解到四种事假绑定的方式

从性能方面考虑,在render方法中使用bindrender方法中使用箭头函数这两种形式在每次组件render的时候都会生成新的方法实例,性能欠缺

constructorbind事件与定义阶段使用箭头函数绑定这两种形式只会生成一个方法实例,性能方面会有所改善

使用 Immutable

在理解Immutable中,我们了解到使用 Immutable可以给 React 应用带来性能的优化,主要体现在减少渲染的次数

在做react性能优化的时候,为了避免重复渲染,我们会在shouldComponentUpdate()中做对比,当返回true执行render方法

Immutable通过is方法则可以完成对比,而无需像一样通过深度比较的方式比较

懒加载组件

从工程方面考虑,webpack存在代码拆分能力,可以为应用创建多个包,并在运行时动态加载,减少初始包的大小

而在react中使用到了Suspenselazy组件实现代码拆分功能,基本使用如下:

javascript">const johanComponent = React.lazy(() => import(/* webpackChunkName: "johanComponent" */ './myAwesome.component'));export const johanAsyncComponent = props => (<React.Suspense fallback={<Spinner />}><johanComponent {...props} /></React.Suspense>
);

 

服务端渲染

采用服务端渲染端方式,可以使用户更快的看到渲染完成的页面

服务端渲染,需要起一个node服务,可以使用expresskoa等,调用reactrenderToString方法,将根组件渲染成字符串,再输出到响应中

例如:

javascript">import { renderToString } from "react-dom/server";
import MyPage from "./MyPage";
app.get("/", (req, res) => {res.write("<!DOCTYPE html><html><head><title>My Page</title></head><body>");res.write("<div id='content'>");  res.write(renderToString(<MyPage/>));res.write("</div></body></html>");res.end();
});
客户端使用render方法来生成HTMLimport ReactDOM from 'react-dom';
import MyPage from "./MyPage";
ReactDOM.render(<MyPage />, document.getElementById('app'));

 

其他

除此之外,还存在的优化手段有组件拆分、合理使用hooks等性能优化手段...

 

 

 


http://www.ppmy.cn/server/13014.html

相关文章

stripe.js踩坑日记

stripe.js踩坑日记 先附上代码【选择支付方式并唤起对应支付后重定向到支付结果页面】 先安装依赖包 npm install stripe/stripe-js代码【vue3语法】 <template><div class"stripe-pay-ment-box"><div id"payment-element"></div…

OEEL高阶应用——matrixUnit()函数的使用

简介 matrixUnit函数是一种用于创建单位矩阵的函数。单位矩阵,又称为恒等矩阵,是一个对角线上元素全为1,其余元素全为0的方阵。单位矩阵的主要特点是在矩阵乘法中起到类似于数乘中的1的作用,即任何一个矩阵与单位矩阵相乘都等于原矩阵本身。 在数学和计算机科学中,单位矩…

linux内核网络源码-用户空间与内核的接口

内核通过各种不同的接口把内部信息输出到用户空间&#xff0c;除了程序员用于请求特定信息的经典系统调用外&#xff0c;还有三个特殊接口&#xff0c;而其中两个是虚拟文件系统&#xff1a; procfs 文件系统 这是一个虚拟文件系统&#xff0c;通过是挂在proc ,允许内核以文件的…

ElasticSearch:基础操作

一、ES的概念及使用场景 ElasticSearch是一个分布式&#xff0c;高性能、高可用、可伸缩、RESTful 风格的搜索和数据分析引擎。通常作为Elastic Stack的核心来使用 我们通过将ES 和 mysql对比来更好的理解 ES&#xff0c;ES和mysql相关的基本概念的对比表格如下&#xff1a; …

数据结构递归算法总结

递归算法时数据结构中的重要思想&#xff0c;但对于算法问题来说&#xff0c;利用递归思想解决问题有几种模式可以总结下来 简单递归 简单直接的调用自己即为简单递归&#xff0c;典型题目&#xff1a; 求解n! function fn(n) {if (n 0) return 1;return n * fn(n - 1); }…

再拓信创版图-Smartbi Insight V11与东方国信CirroData数据库完成兼容适配认证

近日&#xff0c;思迈特商业智能与数据分析软件 [简称&#xff1a;Smartbi Insight] V11与北京东方国信科技股份有限公司 &#xff08;以下简称东方国信&#xff09;CirroData-OLAP分布式数据库V2.14.1完成兼容性测试。经双方严格测试&#xff0c;两款产品能够达到通用兼容性要…

pollLast() 和poll啥区别

在 Java 中&#xff0c;pollLast() 和 poll() 是 Deque 接口的两个不同的方法&#xff0c;它们都用于从双端队列中移除并返回元素&#xff0c;但它们移除元素的位置不同&#xff1a; poll(): poll() 方法从双端队列的前端移除并返回第一个元素&#xff08;即队列的头部&#xf…

qt tcp 连接 秒断连

问题&#xff1a; tcp连接总是秒成功后断连 debug会出现下面这些 onecore\net\netprofiles\service\src\nsp\dll\namespaceserviceprovider.cpp(550)\nlansp_c.dll!00007FFDA2A1D93D: (caller: 00007FFDD8BEACF6) LogHr(1) tid(336c) 8007277C ¡£¡£ one…