反应通量/还原状态不应包含计算数据 - 性能问题?

时间:2015-12-01 10:00:06

标签: performance reactjs flux redux

流量的核心原则之一是让应用程序在商店中处于最低限度。可以根据其他状态数据计算的所有内容都不应该进入商店。

当我有一个多重过滤和排序的列表时,必须从一堆基本状态信息计算最终列表的想法似乎是一个性能问题。 reselect声称在某种程度上解决了这个问题,但是什么反对将最终名单保存为状态?

2 个答案:

答案 0 :(得分:2)

计算列表的一个问题是它们如何与'shouldComponentUpdate'进行交互。如果Redux每次在通量状态发生任何变化时重新执行计算,那么每次最终都会得到一个不同的列表对象,而且shouldComponentUpdate看不到它实际上没有变化(假设它使用某种浅层比较) ),因此React将最终重新渲染依赖于列表的所有组件以进行每次更改。对于大量数据,这可能会使应用程序有点无响应。但是,如果你采用无限滚动技术(即只渲染可见的东西),并且没有可笑的大量可见组件(例如,不是1000个小复选框的网格),很可能没有真正的性能问题重新渲染每一个变化(并让React在渲染的JS树上做它的差异化)。

所有人都说,重新选择(如果你使用ImmutableJS或更类似的方法,更强大的方法)将通过缓存列表计算的结果给你优化,所以如果列表没有,React通常不会重新渲染没改变。

但是,避免多个事实来源,缓存失效问题等,从使计算列表保持在应用程序状态中可能更可取。如果你到处都这样做,那么你最终会得到非常复杂的逻辑来响应变化 - 如果你将派生状态存储了很多并且你的应用程序增长了,很可能会很快变得无法管理......

答案 1 :(得分:1)

(我在你的问题中假设你所谓的状态实际上是应用程序状态,即存储/道具,而不是组件状态)

保持列表与任何缓存一样,在性能和

之间进行权衡
  • 增加内存使用量
  • 可能很复杂的缓存失效逻辑,用于确定列表何时失效

作为一般规则,我会考虑将任何缓存保留为最后应该完成的优化(不要这样做,不要这样做,不要这么做)

此外,如果组件未(重新)安装在每个渲染上,因此通过val conf = new SparkConf() val sc = new SparkContext(conf) val line = sc.textFile(args(0)) line.flatMap(_.split(" ")).map((_, 1)).reduceByKey(_+_).collect().foreach(println) sc.stop() 接收道具更改,则有机会决定是否应重新计算列表。如果不需要,则在componentWillReceiveProps()中返回false将保持列表不变。 (vDOM是缓存)

据说有一个重要因素支持缓存:避免I / O.如果重建列表涉及I / O并且可以安全地假设列表没有更改,则应使用缓存。