關於immutable及其在項目中的使用

一、什麼是Immutable

Immutable是指一旦建立即不可變的數據,全部對Immutable對象進行的修改操做最終都會返回一個新的Immutable對象。其中實現的原理是持久化數據結構(Persistent Data Structure),即使用舊的數據建立新數據時保持舊的數據不變。html

現有的Immutable庫主要有三種:immutable、immer、seamless-immutable。react

二、immutable.js

Facebook 工程師 Lee Byron 花費 3 年時間打造,與 React 同期出現,但沒有被默認放到 React 工具集裏(React 提供了簡化的 Helper)。它內部實現了一套完整的 Persistent Data Structure,還有不少易用的數據類型。像 `Collection`、`List`、`Map`、`Set`、`Record`、`Seq`。有很是全面的`map`、`filter`、`groupBy`、`reduce``find`函數式操做方法。同時 API 也儘可能與 Object 或 Array 相似。https://zhuanlan.zhihu.com/p/20295971編程

immutable.js支持的數據類型主要有redux

(1)Map:鍵值對集合,對應於Object,相似ES6中的Map數組

(2)List:有序可重複列表,對應Array數據結構

(3)Set:無序不可重複列表less

同時immutable還提供了豐富的API對數據進行操做,不論是簡單的對象、數組仍是有嵌套結構的數據,都能快速地對數據進行修改函數式編程

三、why immutable?

背景

與immutable相對應的即mutable(可變的),JavaScript中的數據都是可變的,尤爲針對引用類型的數據,建立對象和數組後對其進行修改,返回仍是指向原對象的指針,這樣的設計是出於節約內存的考慮。然而mutable帶來的負做用也是明顯的,實際react項目中的數據流日趨複雜,redux中維護的state已經不是簡單的對象和數組,一般是多層嵌套的數據結構。在通過屢次action對state的操做後,結構複雜的state會變得難以控制,常常會引發一些自身state沒有改變的組件從新渲染,這會對性能形成不小的影響,相比起來mutable節約內存的優勢也就顯得微不足道。函數

再者,redux中的reducer是純函數,即在原始state的基礎上返回一個新的state,而不是在舊的state上進行修改:工具

  • Redux 的 combineReducers 方法 淺比較 它調用的 reducer 的引用是否發生變化。
  • React-Redux 的 connect 方法生成的組件經過 淺比較根 state 的引用變化 與 mapStateToProps 函數的返回值,來判斷包裝的組件是否須要從新渲染

而要作到不可變數據結構,解決方案有**深拷貝、引入immutable數據。

深拷貝

深拷貝就是生成一份徹底相同,但沒有地址共享的數據。這樣作的代價一般是很是昂貴的,深拷貝的實現須要遍歷數據的每一個節點,遞歸調用自身函數實現,而項目中須要操做的數據體量大,且多爲深層嵌套的結構,這樣作無疑會對性能形成嚴重損耗。因此深拷貝方案不可取!

immutable

immutable爲了不深拷貝帶來的性能損耗,採用結構共享(Structure share)實現對數據的獨立拷貝。即若是對象樹中一個節點發生變化,只修改這個節點和受它影響的父節點,其它節點則進行共享。這樣既能夠用最小的代價實現對數據的獨立拷貝,也不會對內存形成太大負擔。

再者,shouldComponentUpdate是react項目優化中的一個重點。咱們在比較state和props後返回true or false判斷組件是否須要從新渲染,這裏也須要對每一個數據結構進行深層次的比較才能返回正確的結果,不然會形成組件沒必要要的更新或者沒有按照既定狀況更新。針對這種狀況immutable爲咱們提供了immutable.is這個API,能夠在性能較好的狀況下實現immutable對象的深度比較。

因而可知,在項目中引入immutable是能夠以較小代價優化性能的選擇。

四、總結

immutable的優勢

  • 下降mutable帶來的複雜度,實現數據的可追溯
  • 節約內存(結構共享)
  • 與函數式編程理念高度契合

缺點

  • immutable.js庫體積較大,引入項目會增長資源文件大小
相關文章
相關標籤/搜索