美文网首页
整理千牛插件的优化方向

整理千牛插件的优化方向

作者: 打铁大师 | 来源:发表于2018-01-07 23:39 被阅读0次

    下面所有内容,都在千牛内验证过


    1.支持this.props.children

    组件能像HTML标签一样进行嵌套,提升组件的复用。

     <FancyBorder>
      <Text>
        Welcome
      </Text >
      < Text >
        Thank you for visiting our spacecraft!
      </Text >
    </FancyBorder>
    

    FancyBorder组件

    <View>
      {this.props.children}
    </View >
    

    2.setState方法,支持传递函数

    传递函数的例子

    this.setState((prevState, props) => ({
      counter: prevState.counter + props.increment
    }));    
    

    3.不支持合并多个setState

    原因:rax的setState是同步的,react的setState是异步的

    rax原文如下:

    The setState() actions are synchronous, and React setState actions are asynchronous.

    在rax中,多次setState,会导致多次渲染,举个例子:

    press = () => {
        this.setState({ count: this.state.count+1 });
        this.setState({ count: this.state.count+1 });
    }
    

    当调用这个函数后,render方法会被调用两次,意思是,组件更新了两次。

    So 不要像上面那么分开setState,这么做性能并不好。正确做法是:合并成一个setState。


    4.实现内容分发(slot)

    把组件作为属性传给另一个组件

     <SplitPane left={<Contacts />} right={<Chat />} />
    

    SplitPane组件

    <View>
      <View>
        {props.left}
      </View >
      <View>
        {props.right}
      </View >
    </View >
    

    5.指定组件属性的默认值

    目前我们设置属性的默认值方式,可能如下:

    let {name = 'Stranger'} = this.props;
    

    这样做,代码既不美观,又容易产生遗漏,甚至每次使用name前都要设置默认值。

    推荐做法:

     //指定SplitPane组件name属性的默认值
      SplitPane.defaultProps = {
          name: 'Stranger'
      };
    

    最大的有点

    使用defaultProps在某些时候会避免重新渲染(使用shouldComponentUpdate生命周期或PureComponent API的场景下),从而提升性能。


    6.类型检查API(PropTypes)

    看了rax文档,我真想说句MMP,原文如下:

    The PropTypes is only interface React-compatible not really working

    我研究了半天,居然是这个结果,汗!


    7.避免组件无意义渲染,提升应用性能

    每次调用setState都会一次渲染组件,如果前后state或props没有改变,没必要进行重新渲染。为了阻止setState之后,state或props没有变组件依旧渲染的情况,可以使用下面其中一个方法:

    方法一 使用生命周期函数shouldComponentUpdate

    这个函数返回一个布尔值,true表示组件更新,false表示组件不更新。因此,代码可以这样写:

    shouldComponentUpdate(nextProps, nextState) {
       if (nextState.count !== this.state.count) {
           return true
       } else {
           return false
       }
    }
    

    shouldComponentUpdate并不会阻止子组件的render。
    shouldComponentUpdate返回false,componentWillUpdate(),render(),componentDidUpdate()不会触发。

    不推荐使用deep equality 来检查state 或 props的变化,因为这样做效率低,从而可能会降低性能。

    方法二 使用顶级API—— PureComponent

    PureComponent最重要的一个用处就是优化Rax应用,这很容易快速地实现。使用PureComponent对性能的提升是非常可观的,因为它减少了应用中的渲染次数。

    PureComponent改变了生命周期方法shouldComponentUpdate,并且它会自动检查组件是否需要重新渲染。这时,只有PureComponent检测到state或者props发生变化(只是浅比较)时,PureComponent才会调用render方法,因此,你不用手动写额外的检查,就可以在很多组件中改变state.

    可以参考这篇文章,rax的跟react一样


    8.正确使用ref属性

    能用数据(state或props)驱动的,避免使用ref来修改组件。不能用数据驱动的,可以使用ref,比如:让input失去焦点,获得焦点。

    9.最新的react支持这个生命周期componentDidCatch,希望rax能够支持下。

    10.setState()不会触发该组件的componentWillReceiveProps函数

    11.当组件将Unmount的时候,去掉定时器,网络请求,和事件监听,释放系统资源,提升性能。

    目前我们的项目中使用了QN.on,好像没有使用QN.off解绑、注销事件

    举个例子:
    Index组件的click回调中存在如下代码:

      QN.emit('Page.hello');
    

    Index组件render()中存在如下代码

     {
           this.state.show && <Fan name="哇哈哈"/>
      }
    

    Fan组件中存在如下代码:

      QN.on('Page.hello', () => {
          console.log('Page.hello');
      })
    

    当我们不断修改show的值,Fan组件会不断被挂载和取消挂载,如果不在取消挂载前注销事件,那么QN.on监听会不断增多。这时候,执行一次QN.emit会同时触发N个QN.on。

    组件卸载后,原本的定时器,事件监听,和网络请求可能会变得毫无意义,那么请在componentWillUnmount生命周期函数中去掉这些定时器,网络请求,和事件监听。

    相关文章

      网友评论

          本文标题:整理千牛插件的优化方向

          本文链接:https://www.haomeiwen.com/subject/wlnynxtx.html