几个点:
1,尽量减少组件之间的值的传递;
2,减少渲染的次数;
*组件内部的事件的绑定性能调优:
<button onClick={this.handleClick.bind(this)}>one</button>
一般可以这样写 这样写的话 那么 每次render都会重新bind ,效率不高。
<button onClick={()=>this.handleClick()}>two</button>
这样写 每次都render 都会重新生成新的函数,占用更多的内存。效率也不高。
constructor(props){ super(props); this.state={ num:1 }; this.handleClick=this.handleClick.bind(this); }
<button onClick={this.handleClick}>three</button>
这样虽然麻烦但是 只需要绑定一次 性能确实是最高的。 推荐 ;
<p name={{"name":"xiaoming"}}>test</p>
这样写也是 会重新每次渲染都会重新生成 新的对象到内存,性能不行 ;
const name={"name":"xiaoming"};
<p name={name}>test</p>这样写 生成的对象就始终是一个 地址 , 即使每次 render 重复定义name ,那么那个对象也是会被及时销毁并生成新的内村地址。不会占用新的内存 。 推荐
*组件嵌套的渲染性能调优:
在地址栏后加上
/?react_pref
就可以打开chrome的性能调优 工具 performance 看到react 各个组件之间的渲染时间了 ;
我们会发现只有到父组件渲染了那么render函数里子组件 一定会跟着渲染 ,这样就导致了性能的浪费。
通过改写 子组件的生命周期函数----shouldComponentUpdate,我们 可以控制该组件是否渲染
//这个生命周期有入两个参数,第一个是外界渲染导致下一个改变的 props, // 第2个是外界渲染导致下一个改变的 state, shouldComponentUpdate(nextProps,nextState){ //我们在这里作出流程判断,如果当前的prop和传入的props没有变化,返回false不渲染, // 否则props的某个属性发生变化 才渲染; /*这边仅仅做展示用 如果需要比较整个props,那么的话就需要深入的递归循环比较了 * */ if(this.props.num===nextProps.num){ return false } //默认 这个函数会返回true ps:返回true才渲染 ,返回false 就不往下渲染了。 return true }
其实react 还有个组件类叫做 React.PuerComponent; 纯组件 。
和原来的组件一样 换个 继承React组件的类型,这样就可以和上面一样的实现了 ,而且实现的优化更加彻底;
名言 : 共享可变的 状态 是万恶之源 。 这也就是纯函数的编码的好处 ,稳定输出
关于shouldComponentUpdate的实现;
首先两个对象之间的对比:自己递归实现对比
const obj11={name:"xiaoming",info:{age:20}}; const obj22={name:"xiaoming",info:{age:21}}; function comparObj(obj1,obj2) { //如果他们的内存地址一样 ,返回true if(obj1===obj2){ return true; } //如果他们的键的数量不一样 返回false if(Object.keys(obj1)!==Object.keys(obj2)){ return false } for( let key in obj1){ //如果 遇到对象类型 需要比较 ,递归 该函数 并返回递归结果 if(typeof obj1[key] ==="object"){ return comparObj(obj1[key],obj2[key]) } //循环每一项的值 ,如果不一样返回false if(obj1[key]!==obj2[key]){ return false } } // 如果都通过那么return true return true } console.log(comparObj(obj11,obj22) )
react 认为 在shouldComponentUpdate 中 两个对象做比较, 递归比较性能代价太高, 所以默认只支持 对象的浅层比较。
这边我们实现 要使用一个库 , 叫做immutable.js
//Map是这个数据解构的类型定义,is就是做比较 false or true import {Map,is} from "immutable";
shouldComponentUpdate(nextProps,nextState){ return is(nextProps,nextState) }
我们需要把 传入组件的 数据源变成 map的形式
这样就可以实现 对象的对比 ,从而决定是否重新渲染了