簡體   English   中英

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

[英]Redux + ImmutableJS - how to garbage collect too large store?

我正在使用Redux和ImmutableJS。 在我的SPA(非常復雜的管理系統)中,用戶經常將大量數據加載到存儲中(許多表的數千行)。 打開多個頁面並在商店中存儲過多數據后,應用程序變得非常慢,因為ImmutableJS商店甚至可以包含數百萬個條目。

如何從商店“刪除”某些內容,以便數據不會減慢應用程序的速度? 我知道這將違背其主要原則,但你怎么解決呢?

使用具有例如jQuery的通用網站,這將非常簡單。 每次刷新頁面時,所有不必要的內容都會被垃圾回收。 因此,一個頁面的2-3,000個條目就可以了,但是當打開一個新頁面時,reducer會加載新數據,但舊的數據仍然被引用。

當然,我不想強​​迫用戶重新加載頁面。

三重檢查這確實是內存膨脹,而不僅僅是不必要的重新渲染/重新計算

Redux中的變異狀態幾乎總是一個非常糟糕的主意,因為它是庫的一種先決條件。 我的第一個問題是三重檢查你是否因為內存膨脹而導致內存問題,而不是由於不必要的重新渲染或由於不必要的計算。 我的意思是,如果你在同一個地方保存大量數據,請確保你沒有做任何導致React不必要地重新渲染事物或篩選過多數據的東西。

您可以通過司法使用重新選擇庫或使用其他類型的記憶來解決該問題,這些記憶將以避免不必要的重新計算的方式從您的Reducer中檢索數據。 同樣,確保在更改單行時不會不必要地重新渲染整個列表中的每個項目

擺脫對以前狀態的引用

要在JavaScript中編譯垃圾,您只需確保不再引用任何內容

如果你真的需要沿着這條路走下去,那么你必須保持舊頁面的數據“活着”,因為只有JavaScript才會收集不再引用的東西。

Vanilla Redux並沒有堅持以前的狀態。 它正在做的就是將當前狀態保持在let變量中,然后在從調度操作到root reducer獲取新狀態后更改其值(請參閱源代碼 )。

所以,我會確保我沒有使用像之前持續存在狀態的 redux dev工具。

然后在reducer中,創建一個不以任何方式使用以前數據的新對象,而是返回一個包含新數據的新對象:

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

我建議在這里閱讀Chrome的內存分析工具以確保它正常工作。

我建議不要將整個數據保存在商店中,以便將其指向內存解決方案(localstorage,REDIS等)。 我會使用PouncDB並僅在我的商店中存儲_rev修訂號。

關於Immutablejs保持舊數據“活着”的上一篇文章是錯誤的......好吧,從某種意義上說它正在被描述。 Immutablejs使用結構共享,這意味着它只會創建一個新節點和它的子節點,同時與舊數據共享其余的trie。 如果您查看下面的圖像,您會看到右邊的綠色和黃色點是新數據,它與舊數據共享其結構。

舊數據部分(右手藍點) 可用於垃圾收集,只要您不在應用程序的其他位置繼續引用它 如果您想在應用中添加時間旅行功能,那么保持參考最有用。

如果您根據慣用的Redux深入克隆每個對象,那么在沒有immutablejs的結構共享的情況下,您會遇到更大的內存問題。 所以沒有看到一些代碼,我懷疑這里的問題是不可改變的。

你是不是偶然使用toJS() 如果你是,這是一項昂貴的操作,除非絕對必要,否則應該避免。 它還會斷開不可變實例的連接,您將失去結構共享的所有好處。 這是我見過的一個常見錯誤。 您可以訪問值而無需像這樣調用toJS()

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

Lee Byron的演講(immutablejs的創造者)結構分享@ 23:40和垃圾收集@ 24:50

在此輸入圖像描述

由於我看到有人推薦PouchDB,我希望您對reduxdb進行試用,我們已經在生產中使用了近一年,並且沒有發現任何性能問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM