React-性能优化详解

Reactde Dom diff算法使我们能够在任意时间搞笑的重新绘制整个用户界面,并保证最小程度的DOM改变,然而,也存在需要对组件 进行细致优化的情况,这时就需要渲染一个新的DOM来让应用运行得更加高效。

 

1shouldComponentUpdate

当一个组件更新时,无论是设置了新的props还是调用了setState方法,或者forceUpdate方法,React都会调用该组件所有的子组件的render方法。在大多数时候这样的操作都没有问题,除了在render方法十分复杂的页面上,这时会带来下延迟。

 

有时候组件的render方法会在不必要的情况下被调用。比如:组件渲染的过程中,并没有使用props或者state的值,或者组件的props或者state并没有在父组件重新绘染时发生改变。这意味着重新绘染这个组件会得到和已知虚拟DOM一模一样的结果。

 

React提供了一个组件的生命周期方法shouldComponentUpdate,我们可以使用它来帮助React正确判断是否需要调用组件的render方法。shouldComponentUpdate方法返回一个布尔值。如果返回false就是告诉React不要调用组件渲染方法,并使用之前渲染好的虚拟DOM,如果返回true则是让React调用组件渲染方法并计算出新的DOM。在默认情况下,shouldComponentUpadte方法永远都会返回true,因此组件总是会调用render方法。

 

组件首次被渲染时,shouldComponentUpdate方法并不会被调用shouldComponentUpdate方法接受两个参数,即新的props和新的state,以帮助你决定是否应该重新渲染。

 

2、不可变性辅助插件

在需要比较对象以确定是否更新时,使用不可变得数据结构让你的shouldComponentUpdate方法变得更加简单。

我们可以使用Reactaddons.update来确保<SurverEditor />组件得不可变性。

 

3、键(Key

多数时候,你会看到列表中使用key属性的情况,它的作用是给React提供一种除组件类之外的识别一个组件的方法。

举个例子:假设有一个div组件,它的key属性是foo,后续又将它改成了bar,那么React就会跳过DOM diff,同时完全放弃div所有的子元素,并重新从头开始绘染。

在渲染大型子树以避免diff计算时,这样的设计很有用——因为这种计算时浪费时间。除了告诉React什么时候抛弃一个节点之外,很多情况下key还可以在元素顺序改变时候使用,举个例子:

var items=sortBy(this.state.sortingAlgorithm,this.props,items);

return items.map(funciton (item){

return <imgsrc={item.src}/}

});

如果顺序发生改变,React会对元素进行diff操作,并确定出最高效的操作是改变其中几个img元素的src属性。这样的结论其实是非常低效的,同时可能会导致浏览器查询缓存,甚至导致新的网络请求。

要解决这个问题,我们可以给每个img元素简单的添加一些独一无二的字符串或者数字。

return <img src={item.src} key={item.id}/>;

这样React得出的结论就不是改变src属性,而是使用insertBefore操作,而这个操作是移动DOM节点最高效的方法。

 

除了改变顺序外,这个操作同样适用于插入操作(不包括向末尾元素后面插入)。如果没有正确的key属性,在数组开头插入一个项目会导致后续的<img>标签的src属性发生改变。

值得注意的一点是,尽管key看似被作为一个属性传入了,但其实在组件的任何位置都无法实际获取到它。

 

总结

1、将shouldComponentUpdate返回值改为true或者false以提升性能。

2、使用React.addons.Perf来诊断缓慢或不必要的渲染。

3、使用key来帮助,React识别列表中所有子组件的最小变化。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值