Redux + ImmutableJS - 如何垃圾收集太大的商店?

时间:2017-02-13 14:26:17

标签: javascript reactjs redux frontend immutable.js

我正在使用Redux和ImmutableJS。在我的SPA(非常复杂的管理系统)中,用户经常将大量数据加载到存储中(许多表的数千行)。在打开几个页面并且商店中的数据太多之后,应用程序变得非常慢,因为ImmutableJS商店甚至可以包含数百万个条目。

我怎样才能删除"来自商店的东西,以便数据不会减慢应用程序的速度?我知道这会违背其主要原则,但你怎么解决呢?

使用例如jQuery的通用网站,这将非常简单。每次刷新页面时,所有不必要的内容都会被垃圾回收。因此,一个页面的2-3,000个条目就可以了,但是当打开一个新页面时,reducer会加载新数据,但旧的数据仍然被引用。

当然,我并不想强迫用户重新加载页面。

4 个答案:

答案 0 :(得分:4)

三重检查这确实是内存膨胀,而不仅仅是不必要的重新渲染/重新计算

Redux中的变异状态几乎总是真正bad idea,因为它是库的一种先决条件。我的第一个问题是三重检查你是否因为内存膨胀而导致内存问题,而不是由于不必要的重新渲染或由于不必要的计算。我的意思是,如果你在同一个地方保存大量数据,请确保你没有做任何导致React不必要地重新渲染事物或筛选过多数据的东西。

您可以通过司法使用reselect库或使用其他类型的记忆来解决该问题,这些记忆将以避免不必要的重新计算的方式从您的Reducer中检索数据。同样,请确保在更改单行时,整个列表中不是unnecessarily re-rendering every item

删除对先前状态的引用

To get something to be garbage compiled in JavaScript, you just make sure that nothing is referencing it any longer

如果你真的需要沿着这条路走下去,那么你必须保持旧页面的数据“活着”,因为只有JavaScript才会收集不再被引用的内容。

Vanilla Redux并没有坚持以前的状态。它所做的只是将当前状态保持在let变量中,然后在从调度操作到根减速器获取新状态后更改其值(参见source code)。

所以,我会确保我没有使用像persists previous state这样的redux dev工具。

然后在reducer中,创建一个不以任何方式使用先前数据的新对象,而是返回一个包含新数据的新对象:

const data = (state, action) => {
  switch (action.type) {
    case 'RETRIEVE_DATA_SUCCESS':
      return action.payload;
    default:
      return state
  }
}

我建议您阅读Chrome的内存分析工具here,以确保其正常运行。

答案 1 :(得分:3)

我建议不要将整个数据保存在商店中,以便将其指针保存到内存解决方案(localstorage,REDIS等)。我会使用PouncDB并仅将_rev版本号存储在我的商店中。

答案 2 :(得分:1)

关于Immutablejs保持旧数据“活着”的前一篇文章是错误的......好吧,从某种意义上说它正在被描述。 Immutablejs使用结构共享,这意味着它只会创建一个新节点和它的子节点,同时与旧数据共享其余的trie。如果您查看下面的图像,您会看到右侧的绿色和黄色点是新数据与旧数据共享其结构。

旧数据部分(右侧蓝点) 可用于垃圾回收,只要您不在应用程序的其他位置继续引用它 。如果您想为您的应用添加时间旅行功能,那么保持参考是最有益的。

如果每个惯用的Redux都深深地克隆了每个对象,那么在没有immutablejs的结构共享的情况下,你会遇到更大的内存问题。所以没有看到一些代码,我怀疑这里的问题是不可改变的。

您是否偶然使用toJS()?如果你是,这是一项昂贵的操作,除非绝对必要,否则应该避免。它还会断开不可变实例的连接,您将失去结构共享的所有好处。这是我见过的一个常见错误。您可以在不调用toJS()的情况下访问这些值

const immVal = List([1,2,3]) console.log([...immVal.values()])

Lee Byron's talk (creator of immutablejs)结构共享@ 23:40和垃圾收集@ 24:50

enter image description here

答案 3 :(得分:0)

由于我看到有人推荐了PouchDB,我希望您对reduxdb进行试用,我们已经在生产中使用了近一年,并且没有发现任何性能问题。