影响网页性能最大的因素是浏览器的重排(repaint)和重绘(reflow)。react
React的Virtual DOM就是尽量地减小浏览器的重排和重绘。数组
从React渲染过程来看,如何防止没必要要的渲染是解决问题的关键。浏览器
无状态组件只有props和context两个参数。它不存在state,没有生命周期方法,组件自己即有状态组件构建方法中的render方法。性能优化
在合适的状况下,都应该必须使用无状态组件。无状态组件不会像React.createClass和ES6 class会在调用时建立新实例,它建立时始终保持了一个实例,避免了没必要要的检查和内存分配,作到了内部优化。数据结构
纯函数的三大构成原则:dom
纯函数很是方便进行方法级别的测试及重构,它可让程序具备良好的扩展性及适应性。纯函数是函数式变成的基础。函数
React组件自己就是纯函数,即传入指定props获得必定的Virtual DOM,整个过程都是可预测的。性能
拆分组件为子组件,对组件作更细粒度的控制。保持纯净状态,可让方法或组件更加专一(focus),体积更小(small),更独立(independent),更具备复用性(reusability)和可测试性(testability)。测试
PureRender的Pure便是指知足纯函数的条件,即组件被相同的props和state渲染会获得相同的结果。优化
在React中实现PureRender须要从新实现shouldComponentUpdate生命周期方法。shouldComponentUpdate是一个特别的方法,它接收须要更新的props和state,其本质是用来进行正确的组件渲染。当其返回false的时候,再也不向下执行生命周期方法;当其返回true时,继续向下执行。
组件在初始化过程当中会渲染一个树状结构,当父节点props改变的时候,在理想状况下只需渲染一条链路上有关props改变的节点便可;可是,在默认状况下shouldComponentUpdate方法返回true,React会从新渲染全部的节点。
有一些官方插件实现了对shouldComponentUpdate的重写,而后本身也能够作一些代码的优化来运用PureRender。
使用官方插件react-addons-pure-render-mixin实现对shouldComponentUpdate的重写
import React from 'react'; import PureRenderMixin from 'react-addons-pure-render-mixin'; class App extends React.Component { constructor(props) { super(props); this.shouldComponentUpdate = PureRenderMixin.shouldComponentUpdate.bind(this); } render() { return <div className={this.props.className}>foo</div> } }
它的原理是对object(包括props和state)作浅比较,即引用比较,非值比较。好比只用关注props中每个是否全等(若是是prop是一个对象那就是只比较了地址,地址同样就算是同样了),而不用深刻比较。
避免不管如何都会触发shouldComponentUpdate返回true的代码写法。
就算每次传入的数组或对象的值没有变,但它们的地址也发生了变化。
如如下写法每次渲染时style都是新对象都会触发shouldComponentUpdate为true:
<Account style={{color: 'black'}} />
改进办法:将字面量设置为一个引用:
const defaultStyle = {}; <Account style={this.props.style || defaultStyle} />
若是这样绑定事件的话每次都要生成一个新的onChange属性的值:
render() { return <input onChange={this.handleChange.bind(this)} /> }
应该尽可能在构造函数内进行绑定,若是绑定须要传参那么应该考虑抽象子组件或改变现有数据结构:
constructor(props) { super(props); this.handleChange = this.handleChange.bind(this); } handleChange() { ... } render() { return <input onChange={this.handleChange} /> }
JavaScript中对象通常是可变的,由于使用引用赋值,新的对象的改变将影响原始对象。为了解决这个问题是使用深拷贝或者浅拷贝,但这样作又形成了CPU和内存的浪费。
Immutable data很好地解决了这个问题。
Immutable data就是一旦建立,就不能再更改的数据。对Immutable对象进行修改、添加或删除操做,都会返回一个新的Immutable对象。Immutable实现的原理是持久化的数据结构。即便用旧数据建立新数据时,保证新旧数据同时可用且不变。同时为了不深拷贝带来的性能损耗,Immutable使用告终构共享(structural sharing),即若是对象树中一个节点发生变化,只修改这个节点和受它影响的父节点,其余节点则进行共享。