总结了如下几个方面在react上的性能优化react
常见的性能问题场景
web
时刻注意代码的潜在性能问题
chrome
注意可重构的代码,组件化
redux
了解如何使用工具定位性能问题
canvas
JavaScript 语言采用的是单线程模型,也就是说,全部任务只能在一个线程上完成,一次只能作一件事。若是页面比较复杂,添加了大量的计算,而且还添加了Canvas(Canvas 是一个很是受欢迎的表现方式,同时也是WebGL的入口。它能绘制图形,图片,展现动画,甚至是处理视频内容)的绘制,那页面加载可能会卡顿,有可能会呈现出假死状态。
数组
解决方案:在Worker中使用OffscreenCanvas或者将页面渲染时大量的计算放在Worker中。 首先咱们先了解几个概念(以在Worker中用OffscreenCanvas为列)
浏览器
Workers 是一个Web版的线程——它容许你在幕后运行你的代码。将你的一部分代码放到Worker中能够给你的主线程更多的空闲时间,这能够提升你的用户体验度性能优化
OffscreenCanvas并不依赖DOM。bash
OffscreenCanvas学习文档。
另外web workers学习文档请去官网了解
框架
总结: 学习成本比较低,在耗性能的计算和渲染放在Worker中,确实能提高用户体验度
dom节点层次多,并且深,更改state或者更改redux,致使与该数据无相关的dom节点屡次render。
js处理数据过于复杂。定义的状态数据层次过于深。致使对比或者遍历数据消耗性能。
{...this.props} 不要滥用,请只传递component须要的props,传得太多,或者层次传得太深,都会加剧shouldComponentUpdate里面的数据比较负担。
方法绑定的使用
<div onClick={this.tap.bind(this)} />
复制代码
constructor(props) {
super(props);
this.tap= this.tap.bind(this);
}
复制代码
tap = ()=>{};
<div onClick={this.tap} />
复制代码
tap =(value)=> {};
<div onClik={()=>this.tap(value)} />
复制代码
总结:
1.因为绑定是在render中执行,而render是会执行屡次的,每次bind和箭头函数都会产生一个新的函数,于是带来了额外的开销
2.使用构造器bind的方法,每一个实例均可以有效地共享函数体,从而更加有效的使用内存。但当要绑定的函数较多时,这种方法又显得相对的枯燥和无聊。因此,在知道实例很少,函数体不大的前提下,使用箭头函数更加快捷。
3.综合三种写法,第三种是目前最优写法
数组遍历map
map里面添加key,而且key不要使用index(可变的),尽可能使用稳定常量做为key。使用index做为key,只是会让代码不报错,其余一无可取。
每当组件的props或state改变时, React会从新建立一个virtual DOM, 与上一个做对比, 若是发现两个virtual DOM不彻底相同, 则React就会作reconcile, 把有差别的地方更新到真实的DOM上。
使用常量做为key
复制代码
尽可能少用不可控的refs、DOM操做。
props和state的数据尽量简单明了,扁平化。便于数据对比,数组遍历从而减少带来的性能消耗。
使用return null而不是CSS的display:none来控制节点的显示隐藏。保证同一时间页面的DOM节点尽量的少。
在开发前期能够根据业务场景将组件分类
这里咱们就要说一下有状态组件和无状态组件的区别了 就如上所说的展现类组件,这种咱们就能够把它归类为无状态组件,举个列子
import React from 'react';
const PicModal = props => {
const { title = '', content = '', picUrl = '', deviceName = '' } = props;
return (
<div>
<span>title</span>
<span>content</span>
<span>deviceName</span>
{picUrl !== '' ? <img src={picUrl}/> : null}
</div>
);
};
export default PicModal;
复制代码
这样咱们就能够本身封装一个modal组件,根据业务场景不断的迭代优化。 而上面的交互类组件大多数状况下都是有状态组件,维护自身的状态值。可是要实现可复用性,组件之间的耦合度确定是要低的。组件本身控制本身内部的state。这样setState只用局部更新视图。减少性能消耗。
注意:千万不要在父组件定义state,传值给子组件。
1.下降组件之间的耦合度
2.便于后续的组件迭代
根据业务场景将组件拆分的足够细。
下面举一个移动端的列子,web端大多数都会有这种状况,点击项目id列表中projectId,projectList改变。
解决方案:组件1和组件2是经过projectId进行联动。若是咱们拿到这个需求,首先组件化1和2,组件1经过点击id,在父组件中执行getProjectList方法,从而实现渲染组件2。根据组件1中id的state渲染组件1
这样父组件与子组件耦合度很低,子组件本身维护本身的状态值
兄弟组件之间互不影响,经过父组件通讯
若是拆分业务组件的思路不清晰,盲目的将状态值放在父组件中,这样耦合度会大大增长,组件的复用性会大大下降。