资讯专栏INFORMATION COLUMN

React组件性能优化

oysun / 920人阅读

摘要:如果组件是纯函数的,就是给组件相同的和组件就会展现同样的,可以使用这个来优化组件的性能。仅用于拥有简单和的组件。虽然提供简单的来提升性能,但是如果有更特殊的需求时怎么办如果组件有复杂的和怎么办这个时候就可使用来进行更加定制化的性能优化。

React: 一个用于构建用户界面的JAVASCRIPT库.

React仅仅专注于UI层;它使用虚拟DOM技术,以保证它UI的高速渲染;它使用单向数据流,因此它数据绑定更加简单;那么它内部是如何保持简单高效的UI渲染呢?

React不直接操作DOM,它在内存中维护一个快速响应的DOM描述,render方法返回一个DOM的描述,React能够计算出两个DOM描述的差异,然后更新浏览器中的DOM。

就是说React在接收到props或者state更新时,React就会通过前面的方式更新UI。就算重新使用ReactDOM.render(, mountNode),它也只是当作props更新,而不是重新挂载整个组件。所以React整个UI渲染是比较快的。

但是,这里面有几个问题

1. 如果更新的props和旧的一样,这个时候很明显UI不会变化,但是React还是要进行虚拟DOM的diff,这个diff就是多余的性能损耗,而且在DOM结构比较复杂的情况,整个diff会花费较长的时间。

2. 既然React总是要进行虚拟DOM的diff,那么它的diff规则是什么?怎么利用?

PureRenderMixin

针对第一个问题React给我们提供了 PureRenderMixin。
如果React组件是纯函数的,就是给组件相同的props和state组件就会展现同样的UI,可以使用这个Minxin来优化React组件的性能。

var PureRenderMixin = require("react-addons-pure-render-mixin");
React.createClass({
      mixins: [PureRenderMixin],

      render: function() {
        return 
foo
; } });

ES6中的用法是

import PureRenderMixin from "react-addons-pure-render-mixin";
class FooComponent extends React.Component {
      constructor(props) {
        super(props);
        this.shouldComponentUpdate = PureRenderMixin.shouldComponentUpdate.bind(this);
      }

      render() {
        return 
foo
; } }

PureRenderMixin的原理就是它实现了shouldComponentUpdate,在shouldComponentUpdate内它比较当前的props、state和接下来的props、state,当两者相等的时候返回false,这样组件就不会进行虚拟DOM的diff。

这里需要注意:
PureRenderMixin内进行的仅仅是浅比较对象。如果对象包含了复杂的数据结构,深层次的差异可能会产生误判。仅用于拥有简单props和state的组件。

shouldComponentUpdate

React虽然提供简单的PureRenderMixin来提升性能,但是如果有更特殊的需求时怎么办?如果组件有复杂的props和state怎么办?这个时候就可使用shouldComponentUpdate来进行更加定制化的性能优化。

boolean shouldComponentUpdate(object nextProps, object nextState) {
    return nexprops.id !== this.props.id;
}

在React组件需要更新之前就会调用这个方法,如果这个方法返回false,则组件不更新;如果返回true,则组件更新。在这个方法内部可以通过nextProps和当前props,nextState和当前state的对比决定组件要不要更新。

如果对比的数据结构比较复杂,层次较深,对比的过程也是会有较大性能消耗,又可能得不偿失。
这个时候immutable.js就要登场了,也是fb出品,有人说这个框架的意义不亚于React,但是React光芒太强。它能解决复杂数据在deepClone和对比过程中性能损耗。

注意:shouldComponentUpdate在初始化渲染的时候不会调用,但是在使用forceUpdate方法强制更新的时候也不会调用。

render

PureRenderMixin和shouldComponentUpdate的关注点是UI需不需要更新,而render则更多关注虚拟DOM的diff规则了,如何让diff结果最小化、过程最简化是render内优化的关注点。

React在进行虚拟DOM diff的时候假设:

1、拥有相同类的两个组件将会生成相似的树形结构,拥有不同类的两个组件将会生成不同的树形结构。
2、可以为元素提供一个唯一的标志,该元素在不同的渲染过程中保持不变。

DOM结构 

renderA: 
renderB: => [removeNode
], [insertNode

DOM属性

renderA: 
renderB:
=> [replaceAttribute id "after"]

之前插入DOM

renderA: 
first
renderB:
secondfirst
=> [replaceAttribute textContent "second"], [insertNode first]

之前插入DOM,有key的情况

renderA: 
first
renderB:
secondfirst
=> [insertNode second]

由于依赖于两个预判条件,如果这两个条件都没有满足,性能将会大打折扣。

1、diff算法将不会尝试匹配不同组件类的子树。如果发现正在使用的两个组件类输出的 DOM 结构非常相似,你可以把这两个组件类改成一个组件类。

2、如果没有提供稳定的key(例如通过 Math.random() 生成),所有子树将会在每次数据更新中重新渲染。

总结

使用PureRenderMixin、shouldComponentUpdate来避免不必要的虚拟DOM diff,在render内部优化虚拟DOM的diff速度,以及让diff结果最小化。

使用immutable.js解决复杂数据diff、clone等问题。

参考

immutable.js

reconciliation

pure-render-mixin

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/86456.html

相关文章

  • 4、React组件性能优化

    摘要:组件的性能优化高德纳我们应该忘记忽略很小的性能优化,可以说的情况下,过早的优化是万恶之源,而我们应该关心对性能影响最关键的另外的代码。对多个组件的性能优化当一个组件被装载更新和卸载时,组件的一序列生命周期函数会被调用。 React组件的性能优化 高德纳: 我们应该忘记忽略很小的性能优化,可以说97%的情况下,过早的优化是万恶之源,而我们应该关心对性能影响最关键的另外3%的代码。...

    陈伟 评论0 收藏0
  • React-Redux性能优化

    摘要:但是和一起使用还需要一个工具,这一篇就说一下在使用上的一些性能优化建议。如果的改变会引起值变化,那么会调用转换函数,传入作为参数,并返回结果。如果的值和前一次的一样,它将会直接返回前一次计算的数据,而不会再调用一次转换函数。 前面写了两篇文章《React组件性能优化》《Redux性能优化》,分别针对React和Redux在使用上的性能优化给了一些建议。但是React和Redux一起使用...

    JouyPub 评论0 收藏0
  • 使用React.memo()来优化函数组件性能

    摘要:函数组件上面我们探讨了如何使用和的方法优化类组件的性能。它的作用和类似,是用来控制函数组件的重新渲染的。其实就是函数组件的。 原文链接: Improving Performance in React Functional Component using React.memo 原文作者: Chidume Nnamdi 译者: 进击的大葱 推荐理由: 本文讲述了开发React应用时如...

    BetaRabbit 评论0 收藏0
  • 个人常用JavaScript及React常用优化总结

    摘要:插件性能优化及个人常用优化方法经常会触发视觉变化。作用域链指的是当前作用于下可用变量的集合,它在各种主流浏览器中至少包含两个部分局部变量的集合和全局变量的集合。在考虑优化时,数值和变量的性能差不多,并且速度显著优于对象属性和数组元素。 JavaScript 插件性能优化及个人react常用优化方法 JavaScript 经常会触发视觉变化。有时是直接通过样式操作,有时是会产生视觉变化...

    yuanxin 评论0 收藏0
  • React拖拽组件Dragact V0.1.7:教你优化React组件性能与手感

    摘要:但是强迫症犯了,为了使得性能达到极致,再次进行了深度的优化。把移动中心设置在物体的重力中心,最为舒适。你可以狠狠的点击预览地址到此,组件,无论从性能,还是手感上来说,都已经相当的符合我们的需求了。 仓库地址:Dragact手感丝滑的拖拽布局组件 预览地址:支持手机端噢~ 上回我们说到,Dragact组件已经进行了一系列的性能优化,然而面对大量数据的时候,依旧比较吃力,让我们来看看,优化...

    fizz 评论0 收藏0

发表评论

0条评论

oysun

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<