深入浅出React和Redux学习笔记(五)

React组建的性能优化

性能优化的方法:

  1. 单个React组件的性能优化;
  2. 多个React组件的性能优化;
  3. 利用reselect提高数据选取的性能;

重点关注的是,React组件的渲染性能优化。

1.单个React组件的性能优化

React利用Virtual DOM来提高渲染性能,虽然每次页面更新都是对组件的重新渲染,但并不是将之前渲染的内容全部抛弃重来,借助Virtual DOM,React能够计算出DOM树最少的修改,这就是React在默认情况下都渲染很迅速的秘籍。

1.1发现浪费的渲染时间

发现浪费的渲染时间,需要在Chrome浏览器中安装React Perf扩展。

注意:这里的浪费是计算Virtual DOM的浪费,而不是访问DOM树的浪费。

1.2性能优化的时机

“过早的优化是万恶之源” - 高德纳 《计算机编程艺术》

表面上的意思是,除非性能出了问题,不然就不要花时间去优化性能问题。

真正上的意思是,“我们应该忘记忽略很小的性能优化,可以说97%的情况下,过早的优化是万恶之源,而我们应该关心对性能影响最关键的那另外的3%的代码” - 高德纳。

高德纳认为,不要将性能优化的经历浪费在对整体性能提高不大的代码,而是对性能有关键的影响的部分,优化并不嫌早。

“过早的优化”:没有任何量化证据的情况下,开发者对性能优化的猜测,并没有可测量的性能指标,就完全不知道当前的性能瓶颈在何处,完成优化之后,也无法知道性能优化是否达到了预期的结果。

1.3React-Redux的shouldComponentUpdate实现

shouldComponentUpdate的默认实现是一种兜底的保险方法。但是要达到更好的性能,有必要定义shouldComponentUpdate函数。

React-Redux通过提供更好的shouldComponentUpdate的实现方式:

在对比prop和上次渲染所用prop方面上看,依然使用的是“浅层比较”(shallow compare)。可以简单的理解为,JS 的“===”操作符。

想让React-Redux认为前后的对象prop是相同的,就必须保证prop指向的JS对象是一致的。

2.多个React组件的性能优化

和单个React组建的生命周期一样,多个React组件也要考虑三个阶段:装载更新卸载

装载阶段:

React组件往下的所有子组件,都需要彻底渲染一次,都要经历一遍React组件的装载生命周期。因此,没有多少性能优化的东西。

卸载阶段:

只有一个生命周期函数componentWillUnmount,只是清理componentDidMount,做的事情比装载阶段还少,也没有什么可优化的空间。

值得关心的过程,只剩下更新阶段。

2.1React的调和(Reconciliation)过程

在装载的过程中,React通过render方法在内存中产生了一个树形结构,树上每一个节点代表一个React 组件或者原生DOM元素,这个树形结构就是所谓的Virtual DOM。React根据这个Virtual DOM 来渲染浏览器的DOM树。

Reconciliation(调和)

在更新阶段巧妙地原有的Virtual DOM和新生成的Virtual DOM,找出两者的不同之处。根据不同来修改DOM树,更新中这个“找不同”的过程就叫做Reconciliation(调和)。

Reconciliation算法:

当React要对比两个Virtual DOM的树形结构时,从根节点开始递归往下对比,在这个树形结构中,每个节点都可以看作当前节点以下部分子树的根节点。所以这个对比算法可以从Virtual DOM上任何一个节点开始执行。

React首先检查两个树形的根节点的类型是否相同,根据相同或者不同有不同处理方式。

  1. 节点类型不同的情况

    如果树形结构根节点类型不相同,直接认为原来的树形结构已经没有用,需要构建新的DOM树。原有的树形上React组件会经历“卸载”的生命周期。这种方式可能造成某种程度的浪费,但是为了避免较大的复杂度,React必须选择一个更简单跟快捷的算法。

    也就是说,对于Virtual DOM树这是一个“更新”的过程,但是却可能引发这个树结构上某些组件的“装载”和“卸载”过程。

  2. 节点类型相同的情况

    如果两个树形结构的根节点类型相同,React就认为原来的根节点只需要更新过程,不会将其卸载,也不会引发根节点的重新装载。

    区分节点的类型:

    1. DOM元素类型,对应的是HTML直接支持的元素,如div、span、p;

      React会保留节点对应的DOM元素,对树形根节点上的属性和内容做对比,只更新修改的部分。

    2. React组件,利用React库定制的类型;

      React根据新节点的props去更新原来根节点的组件实例,引发组件实例的更新过程,也就是按照顺序引发下列函数:

      • shouldComponentUpdate
      • componentWillReceiveProps
      • componentWillUpdate
      • render
      • componentDidUpdate

      在这个过程中,如果shouldComponentUpdate函数返回false,那么更新过程停止。为了保持最大的性能,每个人React组件必须要重视shouldConponentUpdate,如果发现没有必要重新渲染,那么直接返回false。

      在处理完根节点的对比之后,React的算法会对根节点的每个子节点重复一样的动作,这时候每个子节点就成为它所覆盖部分的根节点,处理方式和它的父节点完全一样。

    3. 多个子组件的情况

      当一个组件包含多个子组件的情况,React的处理方式也非常直接。

      React选择了看起来很傻的办法,不是寻找两个序列的精确差别,而是直接挨个比较每个子组件。

2.2Key的用法

如果在代码中明确地告诉每个组建的唯一标识,就可以帮助React在处理这个问题时聪明很多,告诉每个组件“身份证号”的途径就是key属性。

在一列子组件中,每个子组件的key值必须唯一,不然就没有帮助React区分各个组件的身份。

如果key值不唯一,就会误导React做出错误的判断,甚至导致错误的渲染结果。

注意:虽然key是个prop,但是接受可以的组件并不能读取到key的值,因为key和ref是React保留的两个特殊prop,并没有预期让组件直接访问。

3.利用reselect提高数据选取的性能

3.1两阶段选择过程

reselect库的工作原理:只要相关状态没有改变,那就直接使用上一次的缓存结果。

reselect的计算过程分为两个步骤:

  1. 从输入参数state抽取第一层结果,将这一层结果和之前抽取的第一层结果做比较,如果发现完全相同,就没有必要进行第二部分运算,选择器直接把之前第二部分的运算结果返回就可以了。
  2. 根据第一层结果计算出选择器需要返回的最终结果。

使用reselect需要安装对应的npm包:

$ npm install --save reselect

Redux要求每个reducer不能修改state状态,如果要返回一个新的状态,就必须返回一个新的对象。

3.2范式化状态树

Redux的状态树应该设计的尽量扁平,使用reselect之后,状态树的设计应该尽量范式化(Normalized)。

范式化:就是遵照关系型数据库的设计原则,减少冗余数据。

范式化的数据结构就是要让一份数据只存储一份,数据冗余造成的后果就是难以保证数据一致性。

反范式化是利用数据冗余来换取读写效率。

反范式化数据结构的特点就是读取容易,修改比较麻烦。

对比反范式化和范式化方式的优劣,不能看出范式化更加合理。因为虽然join数据需要花费计算时间,但是应用reselect之后,大部分情况下都会命中缓存,实际也就是没有花费很多计算时间。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
代码下载:完整代码,可直接运行 ;运行版本:2022a或2019b或2014a;若运行有问题,可私信博主; **仿真咨询 1 各类智能优化算法改进及应用** 生产调度、经济调度、装配线调度、充电优化、车间调度、发车优化、水库调度、三维装箱、物流选址、货位优化、公交排班优化、充电桩布局优化、车间布局优化、集装箱船配载优化、水泵组合优化、解医疗资源分配优化、设施布局优化、可视域基站和无人机选址优化 **2 机器学习和深度学习方面** 卷积神经网络(CNN)、LSTM、支持向量机(SVM)、最小二乘支持向量机(LSSVM)、极限学习机(ELM)、核极限学习机(KELM)、BP、RBF、宽度学习、DBN、RF、RBF、DELM、XGBOOST、TCN实现风电预测、光伏预测、电池寿命预测、辐射源识别、交通流预测、负荷预测、股价预测、PM2.5浓度预测、电池健康状态预测、水体光学参数反演、NLOS信号识别、地铁停车精准预测、变压器故障诊断 **3 图像处理方面** 图像识别、图像分割、图像检测、图像隐藏、图像配准、图像拼接、图像融合、图像增强、图像压缩感知 **4 路径规划方面** 旅行商问题(TSP)、车辆路径问题(VRP、MVRP、CVRP、VRPTW等)、无人机三维路径规划、无人机协同、无人机编队、机器人路径规划、栅格地图路径规划、多式联运运输问题、车辆协同无人机路径规划、天线线性阵列分布优化、车间布局优化 **5 无人机应用方面** 无人机路径规划、无人机控制、无人机编队、无人机协同、无人机任务分配 **6 无线传感器定位及布局方面** 传感器部署优化、通信协议优化、路由优化、目标定位优化、Dv-Hop定位优化、Leach协议优化、WSN覆盖优化、组播优化、RSSI定位优化 **7 信号处理方面** 信号识别、信号加密、信号去噪、信号增强、雷达信号处理、信号水印嵌入提取、肌电信号、脑电信号、信号配时优化 **8 电力系统方面** 微电网优化、无功优化、配电网重构、储能配置 **9 元胞自动机方面** 交通流 人群疏散 病毒扩散 晶体生长 **10 雷达方面** 卡尔曼滤波跟踪、航迹关联、航迹融合

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值