zoukankan      html  css  js  c++  java
  • react 性能优化

    默认的渲染行为

     初始情况下,组件树中所有组件都进行了虚拟dom的生成(绿色)

    接着组件进行setState(红色节点),然后重新生成虚拟dom(蓝色节点),生成的虚拟dom树再与之前的对应节点的虚拟dom进行diff,然后对差异进行应用

    针对以上过程可以发现,假如setState没有影响到子组件,或者只影响到了一个子组件(通过props传递了state),则另外没有受影响的子组件的虚拟dom生成是无用的(因为子组件不需要发生变化)。对于这部分虚拟dom的生成以及对比,是无用功。

    渲染优化

      针对以上问题,如何在不需要dom更新的时候,避免虚拟dom的比较呢?

      只需要在shouldComponentUpdate(nextProps,nextState)中判断state和props,如果没有发生变化,则返回false即可(这个函数默认实现是直接返回true),返回true代表重新生成虚拟dom,新旧虚拟dom进行对比,然后局部刷新;返回false,不刷新,没有刚才这一系列步骤,具体可以去查看生命周期,返回true会少执行多个方法。

      假如以下浅蓝色节点设置了state和props的判断(相同返回false),则当红色节点setState的时候,只会生成一颗包含了两个虚拟dom节点的树(蓝色),diff的时候也仅仅针对这两个节点进行diff,效率得到提升。

    基本的做法是在这个函数中,检查state和props有没有发生变更,用当前的状态与新状态(nextXXX)进行深比较:

     shouldComponentUpdate: function (nextProps, nextState) {
         return !isDeepEqual(this.props,nextProps) || !isDeepEqual(this.state,nextState);
     }

    但是深度比较消耗资源,官方推荐使用immutable,这样一来每次变动,都会创建新的对象,两者进行 == 比较(浅比较,shallow equal)即可,而不再需要深比较了。

    使用Immutable

    在react class中的getInitialState中返回一个Immutable数据(或者在constructor中把state初始化,设置immutable数据),然后其他地方通过state.xx获取到immutable数据,进行修改。把修改后的值重新setState回去。

    PureRenderMixin:会自行为组件添加shouldComponentUpdate,实现对props和state的浅比较。但这个不能直接拿来使用,因为是浅比较。这就必须配合上immutable来使用了。

    PureComponent:react15中用来替代PureRenderMixin,两者有一样的功能。

    Redux的默认性能优化

    官方有以下两个规定,违背这两个规定会导致redux的默认性能优化不起作用:

    1. 容器型组件必须为Pure Component,即组件只依赖于state和props
    2. 全局状态树(global state)的任何变动都是immutable的

    通过connect生成的容器中,就默认提供了shouldComponentUpdate函数,其中对props和state进行了浅比较。

    列表元素的key值

    当渲染一个列表的时候,列表元素标签上没有key属性,会出现一个警告

    a key should be provided for list items 

     元素的key值在兄弟元素之间应该是唯一的,但不需要全局唯一。

    使用key的好处是利于dom的复用,查看:http://www.cnblogs.com/hellohello/p/7988346.html

    误区

    不要在render中创建新对象(或函数),然后模板中引用这个新对象:

    render() {
        const {items} = this.props;
        const newData = { hello: 'world' };
        return <Item name={name} data={newData} />
    }

    这样在Item的内部shouldComponentUpdate中判断props时总会不一致,会令Item每次都进行渲染

    解决办法是:转化为满足 === 判断的数据,再传递。

  • 相关阅读:
    Python 日期格式化 及 schwartzian排序
    好的数据源
    董的博客 hadoop
    hadoop 2.2.0 集群部署 坑
    python 单元测试
    减少前端代码耦合
    jQuery $.ajax传递数组的traditional参数传递必须true
    如何做一个大格局的人
    中国各省市县级 JSON 文件
    用v-for进行table循环
  • 原文地址:https://www.cnblogs.com/hellohello/p/8057303.html
Copyright © 2011-2022 走看看