react性能优化:redux的store中的数据量太大是否会影响性能

  最近在处理大list(infinite scroll view)时,发现元素多了之后react渲染开始变得卡顿,想找一找问题出在哪里了,在参考了一些博客和做了一番研究之后,给大家来个总结。redux的store中的数据量太大,肯定是会影响性能的,但是跟其本身占的内存并没有太大关系,影响的是一些别的东西,请往下看。

  1.action触发大量reducer的开销

https://github.com/omnidan/redux-ignore,可以防止触发跟某reducer不相关的其他action。

  2.state树的内存开销(没有太大关系)

  所谓的state tree就是一个json object。在栈里面存了一个引用,在堆里面存了一个对象,就算state树很大层级很多,基本也不可能达到G级别的,况且,在正确设计state树的情况下,这是不可能也不合理的,redux推荐设计尽可能最小化的state树,只放必要的节点,其他的应该交由组件自己的state来维护。

  3.通过connect()连接store的subscriber,在store改变时被触发的开销

  如果每个UI component都连接一堆props到store自然是很恐怖的,因此redux推荐只在最外部的组件中做connect,也就是container,然后在container中引用其他component来渲染,component自身的一些状态改变可以用react自己的state来维护。

  4.渲染大型虚拟DOM的开销

  首先react-redux框架中的connect已经帮我们优化了最外层的container,只会渲染改变的部分,至于container中的其他component,可以通过shouldComponentUpdate()来判断是否重新渲染组件,这也是可以轻松完成的性能优化。但是当处理大list时(上拉无限加载),在dom元素越来越多时,渲染还是明显会出现卡顿,虽然react只会将虚拟dom改变的部分渲染到真实dom(暂且相信react在大量数据下的diff算法,官方说很高效,事实也确实如此),但是如果改动部分的dom节点本身就是一个庞大的量级(比如一次性改变或插入一万个dom节点),那么渲染就会卡顿,redux作者做过一个压力测试,结论是渲染一万个node时,操作会有轻微的延迟。当然,正常的app应该是不会有上千node的,假如真的有,那绝大部分都不是用户可见的(比如一个很长很长的scroll view,切换tab回来的时候还保持滚动位置,不自动刷新dom,就会导致一次性重新插入大量dom)。这样情况下,可以用 react-infinite https://github.com/seatgeek/react-infinite,原理是只渲染用户能看见,以及即将看见的。其余的都合并起来放在一个dummy node里。

  结语:最好的优化就是不碰到瓶颈前别瞎优化