网页性能最大的限制因素是浏览器重绘(reflow)和重排版(repaint),React的虚拟DOM就是为了尽量减小浏览器的重绘和重排版,从React的渲染过程看,避免没必要要的渲染能够进一步提升性能。react
React优化方法中最多见的就是PureRender,PureRender的原理是从新实现shouldComponentUpdate生命周期方法,让当前传入的state和props和以前的作浅比较,若是返回FALSE,组件就不执行render方法,默认状况返回TRUE。react-addons-pure-render-mixin插件容许咱们在ES6 的classes语法中使用PureRender:浏览器
import React,{component} from ‘react’; import PureRenderMixin from ‘react-addons-pure-render-mixin’; class App extends Component{ constructor(props){ super(props); //!!! this.shouldComponentUpdate = PureRenderMixin.shouldComponentUpdate.bind(this); } render(){ return <div calssName = {this.props.className}>foo</div>; } }
在传递数据时,能够经过Immutable Data进一步提高组件的渲染性能,Immutable Data是针对可变对象和不可变对象所作的折衷。可变对象是指多个变量引用一个对象,这致使对象的time和value耦合,对象一旦改变没法重塑;不可变对象是指每次用到一个对象就进行深复制,这致使内存浪费;Immutable Data实现的原理基于持久化数据结构,也就是使用旧数据建立新数据时,旧数据依旧保存,并且为了不深度复制,Immutable Data使用结构共享,也就是说,若是对象树中的一个节点变化,只修改这个节点和受他影响的父节点,其余节点依旧共享。Immutable Data优势体如今下降了可变数据带来的时间和值的耦合;节省了内存,能够实现数据的时间旅行,也就是说数据能够重塑。数据结构
使用Immutable Data能够直接采用Facebook开发的immutable.js库,该库具备完善API,而且和原生JavaScript对象对应。Immutable Data能够和PureRender结合使用,前面提到,PureRender经过浅比较肯定shouldComponentUpdate的返回值,可是浅比较能够覆盖的场景很少,深比较成本昂贵。而Immutable.js提供了高效判断数据是否改变的方法,只须要全等算符(===)和自带的is()方法就能够知道是否执行render方法,这个操做几乎是零成本的,因此能够极大地提升性能。使用immutable data以后,仅仅改变状态了的组件及其父组件被从新渲染。性能
import React,{ commponent } from 'react'; import { is } from 'immutable'; class App extends Component { shouldComponentUpdate(nextProps, nextState){ const thisProps = this.props || {}; const thisStae = this.state || {}; if (Object.keys(thisProps).length !== Object.keys(nextProps).length || Object.keys(thisState).length !== Object.keys(nextState).length){ return true; } for (const keys in nextProps){ // !==判断原生对象,is判断immutable对象 if (thisProps[key] !== nextProps[key] || !is(thisProps[key], nextProps[key])) return true; } for (const key in nextState){ if ( thisStae[key] !== nextState[key])|| !is(thisStae[key],nextState[key]) return true; } } }
问题:Immutable Data能够和PureRender结合使用是简单的做用叠加吗?优先级哪一个更高呢?这种做用叠加有没有性能损耗呢?我当前的理解是,react-addons-pure-render-mixin插件引的PureRender有缺陷,由于浅复制有时会致使比较失误,immutable.js仅仅是弥补了这一问题,反而增长了代码量,那为何不干脆将PureRender去掉,只用immutable.js呢?优化