React项目优化小结

前段时间,我们组花了些时间去优化了一下我们一个react项目,主要是营收下降了而且还被客户投诉了,说是使用太卡顿,周五收到的消息,老板让我们尽快解决这个问题,没办法只能硬着头皮上,接下来就是各种总结会,然后就是一系列的讨论,我记得那天讨论的很晚,列出了以下几个影响性能的点:

1、部分大数组有多次迭代

2、主体识别上线导致了必然的卡顿还在没有弄清楚async/await的情况下使用了他,结果陷入了async/await地狱。

3、一个数据的变更会导致大量组件重新渲染,这是相当大的一个开销,也是从我们做项目就一直存在的问题。

第二天周六我和组长就过去加班着手优化工作了

对于第一个问题,我们对代码做了优化,尽可能的避免多次迭代,尤其是大数组的迭代。

第二个问题我们参考了如何避免async/await地狱对代码进行了一定程度的调优,然后run了一下项目,虽然流畅度有提升,但还不是很理想,卡顿问题七九存在,尤其是在IE上基本还处于不可用状态,接着我们就把目光放到了第三点,因为这个是一个从一开始做项目我们就知道的点,我们曾经也做过一些优化尝试,比如对一些组件加shouldComponentUpdate来减少一些不必要的重绘,但是结果引入了更多的问题,现在我们的项目已经很复杂了,项目中还使用了redux,只有部分顶层容器组件才连接到了store,父子组件件的数据是通过props来进行的,而且很多子组件都是直接传递了一个大对象给他而不是小组件确切关心的那部分小数据,这样导致大对象中任意一个变量d所以对于渲染次数的优化,可以从两方面入手:

1、更改组件之前传递的数据,尽可能传子组件关心的小数据,而不将一个大对象传下去让子组件自己去取,但是这个方式改动量太大,并不是一天两天能完成的。

2、还是从shouldComponentUpdate入手, 对于函数来说有个截留的概念,shouldComponentUpdate也是一个函数,我们能不能做截留呢?顺着这个思路我们写出了第一段代码:

...
shouldComponentUpdate() {
  this.timer && clearTimeout(this.timer);
  this.timer = setTimeout(() => {
    return true;
  });
  return false;
}
...

使用过react的人一看就知道这段代码不仅达不到我们想要的效果还会带来新的问题,难道这条路行不通吗?我们可以换个思路,react组件我们可以看做是一个类,类中有很多方法,shouldComponentUpdate是其中一个,函数的this指向了组件这个类,那么我们是不是可以直接调用组件渲染方法呢?结果这个此方法是可行的,不过调用的不是render方法而是另外一个forceUpdate的方法,最终代码:

...
shouldComponentUpdate() {
  this.timer && clearTimeout(this.timer);
  this.timer = setTimeout(() => {
    this.forceUpdate();
  });
  return false;
}
...

放上项目跑一发试试,结果流畅度提升了不知道多少倍,如果以前的速度是用走的,那现在就是用飞的有木有,再上IE看一番,这速度也是不知道提升了多少倍,妈妈再也不用担心我们的项目在IE上的运行速度了。

当然这种做法是相当暴力的,但是这个暴力的做法确实造就了奇迹,达到了我们想要的效果,所以在使用这种方法时,一定要慎重,虽然这个做法不会直接对数据产生影响,但是如果出问题对于渲染来说影响是很大的,不过相对于其他做法来说确实容易了很多,而且影响也减少了不少。

记完,收工!

  • 支付宝二维码 支付宝
  • 微信二维码 微信
相关文章