打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
[心得] 如何提高 React App 的性能


这篇是我最近在研究React.js时的一些心得,关于怎么使用 shouldComponentUpdate 及 immutable.js 提高性能。

Virtual DOM

因为使用传统的方式对DOM 进行操作会很慢,为此React 设计了 Virtual DOM 这个中间层来降低操作 DOM 的成本。


Virtual DOM 是一个类似实际 DOM 节点的树状结构,当有数据改变时才会透过 diff 算法计算最小差异并更新到实际的 DOM 上。


所以当我们 render 时,其实都是 render 到 Virtual DOM 上,React 会自己帮我们算出最小差异然后更新。


shouldComponentUpdate

在讲 shouldComponentUpdate 之前,先来看看 Component 的生命周期。当 state 或是 props 改变的时候,会先呼叫 shouldComponentUpdate(),如果回传 true 才会 render 到Virtual DOM,最后再由React 的 diff 算法决定要怎么更新 Real DOM。


因为 shouldComponentUpdate() 预设是回传 true,也就是 “一律重绘”,所以不管有没有改变,一律重新 render到Virtual DOM 上,最后由 diff 算法判断到底哪些需要改变。


虽然 React 的 diff 算法很高效,但如果数量一多,React 要递归跑完所有component 的 render,还是会拖慢速度,所以可以自己实现shouldComponentUpdate,如果数据相同就不要重新 render。


定义一个命叫 Item的Component:

// <Item content='item1' />
var Item = React.createClass({    render(){
       return <h1> {this.props.content} </h1>;    }});

可以加入一个shouldComponentUpdate(nextProps, nextState):

shouldComponentUpdate(nextProps, nextState){
   if(this.props.content !== nextProps.content) return true;
   return false;}

只有在this.props.content改变的时候才重新 render,这样就可以大大减少重新render 的次数。

可能会遇到什么问题?

可能会遇到props是对象或者数组的情况,但对象跟数组没办法比较相等,看看下面的例子:

var obj1 = {name: 'Larry', age: 19};
var obj2 = {name: 'Larry', age: 19};

console.log(obj1 === obj2);//false
console.log(obj1.name === obj2.name && obj1.age === obj2.age);//true

var
arr1 = [1, 2, 3];
var arr2 = [1, 2, 3];

console.log(arr1 === arr2);//false

// 比較 array 內所有元素 -> true
console.log(function(){
   if(arr1.length != arr2.length) return false;
   for(var i=0 ; i<arr1.length ; i ){
       if(arr1[i] !== arr2[i]) return false;    }
   return true;}());

用===只能比较是不是同一个对象,如果要比较内容的话要自己进行比较,数组也是要自己遍历整个数组,所以shouldComponentUpdate可能会写成这样:

// <List items={['item1', 'item2', 'item3']} />

shouldComponentUpdate(nextProps, nextState){
   if(this.props.items.length != nextProps.items.length) return true;
   for(var i=0 ; i<this.props.items.length ; i ){
       if(this.props.items[i] !== nextProps.items[i]) return true;    }
   return false;}

但因为是遍历整个数组,如果数量一多的话还是会很慢,这时候就可以用immutable.js加速。

Immutable.js

immutable.js 是由Facebook 开源的一个 library,提供各种不同的结构,可以用npm install immutable安装。


比较常用的有 List 跟 Map,immutable.js 中的 List 就像是 Array

var Immutable = require('immutable');
var list1 = Immutable.List.of('a', 'b', 'c');
// ['a', 'b', 'c']
var list2 = Immutable.List.of('a', 'b', 'c');
// ['a', 'b', 'c']

console.log(Immutable.is(list1, list2));
// true
console.log(list1.get(0));
// 'a'
list1 = list1.set(0, 'b');
// list1 = ['b', 'b', 'c']
console.log(Immutable.is(list1, list2));
// false

immutable.js 中的 Map 就像是Object

var map1 = Immutable.Map({name: 'Larry', age: 19});
var map2 = Immutable.Map({name: 'Larry', age: 19});

console.log(Immutable.is(map1, map2));
// true
map1 = map1.set('name', 'Larry Lu');
// map1 = {name:'Larry Lu', age:19}

console.log(map1.get('name'));
// 'Larry Lu'
conosle.log(Immutable.is(map1, map2));
// false

这样就可以用Immutable.js来比较数组跟对象,而且Immutable.js不是把每个值都取出来比较,而是在创建 List 跟 Map 时就计算得到一个 hashvalue,比较时就比较那个 hashvalue,所以速度会快非常多。


还有一个要注意的点,immutable.js创造出来的对象是不可变的,在 js 内要更改数组内的元素只要使arr[index] = value,但用immutable.js时要使list = list.set(index,value)。因为set时不会更改原本的而是创造一个新的List,map也是一样,所以一定要使map = map.set('name','Larry Lu')。

结论

综合shouldComponentUpdate 及 Immutable.js 之后,最后就可以把 component 写成这样:

// <Item info={Immutable.Map({'name': 'Larry', age: 19})} />

var Item = React.createClass({    shouldComponentUpdate(nextProps, nextState){
       return !Immutable.is(this.props.info, nextProps.info);    },    render(){
       return (
           <div>                <h1> {'name: ' this.props.name} </h1>                <h2> {'age: ' this.props.age} </h2>            </div>        );    }});

这样就可以减少重新 render 的次数,而且在判断要不要重新 render 时也可以非常快速,让原本就很快的 React 变得更快。


【React启蒙系列文章】

一、[React启蒙系列] 初探React

二、[React启蒙系列] 学习React前需要理解的名词

三、[React启蒙系列] React和Babel的基本使用


【您可能感兴趣的文章】

一、手把手教你用react

二、React入门及资源指引

三、利用ESLint检查代码质量

四、构建一个安全的 JavaScript 沙箱

五、入门Webpack,看这篇就够了

六、第三届CSS大会广州找场地啦~~求介绍~~

七、Web Components 是个什么样的东西

八、JavaScript 被忽视的细节



前端圈--打造专业的前端技术会议

为web前端开发者提供技术分享和交流的平台

打造一个良好的前端圈生态,推动web标准化的发展

官网:http://fequan.com

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
React移动web极致优化
react-生命周期
什么时候要在React组件中写shouldComponentUpdate?
chapter1-React基本语法
facebook开源前端UI框架React初探
常见 React 面试题
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服