摘要:如果實(shí)現(xiàn)了結(jié)構(gòu)共享,每次的新值共享內(nèi)部結(jié)構(gòu)以大幅減少內(nèi)存占用。這意味著,如果對(duì)一個(gè)進(jìn)行賦值次,并不會(huì)創(chuàng)建倍大小的內(nèi)存占用數(shù)據(jù)。消除了流經(jīng)系統(tǒng)的精神負(fù)擔(dān)。代價(jià)是編寫風(fēng)格將顛覆式的完全不同。會(huì)帶來很多無必要的渲染并成為性能瓶頸。
Part01 Immutable由何而生
說immutable之前,首先看下什么是mutable。js在原生創(chuàng)建數(shù)據(jù)類型即是mutable,可變的。
const只是淺層次的防篡改,層級(jí)一深就沒轍了。
js在創(chuàng)建變量、賦值后是可變的。除了基本類型,其他的引用類型,通過變量地址來共享。
改變了obj1.a的值,同時(shí)也會(huì)改變obj.a的值。其實(shí)改變的是同一個(gè)對(duì)象引用。這樣共享地址來共享值的好處是節(jié)省內(nèi)存,壞處是稍微不注意就會(huì)導(dǎo)致改A壞B的棘手問題。
一般的解法就是使用深拷貝而非淺拷貝,生成一份基本類型值完全相同但是沒有共享地址的數(shù)據(jù),除了浪費(fèi)內(nèi)存之外,深拷貝復(fù)雜引用類型時(shí)需要深度遍歷,這樣的做法在React這樣頻繁更新數(shù)據(jù)和對(duì)數(shù)據(jù)更新性能有要求的場(chǎng)景,深拷貝是一個(gè)不優(yōu)雅不推薦,say no的選擇。
那怎么做呢,這個(gè)時(shí)候Immutable就可以閃亮登場(chǎng)解決這個(gè)問題,為什么呢?
相對(duì)于mutable,Immutable就是在創(chuàng)建變量、賦值后便不可更改,若對(duì)其有任何變更,就會(huì)回傳一個(gè)新值
Immutable只是一個(gè)定義,有各種實(shí)現(xiàn),Immutable.js就是facebook工程師實(shí)現(xiàn)js的Immutable歷時(shí)三年的燒腦之作。甚至有些語言天生就是不可變數(shù)據(jù)結(jié)構(gòu),比如國內(nèi)react的早期先驅(qū)題葉極力推崇的ClojureScript。
每次返回新值,大家可能會(huì)覺得性能也并不好啊,又占內(nèi)存之類的。如果實(shí)現(xiàn)了結(jié)構(gòu)共享,每次的新值共享內(nèi)部結(jié)構(gòu)以大幅減少內(nèi)存占用。這意味著,如果對(duì)一個(gè)Immutable進(jìn)行賦值1000次,并不會(huì)創(chuàng)建1000倍大小的內(nèi)存占用數(shù)據(jù)。
與原生JS的mutable語義強(qiáng)烈沖突
除非從零開始一個(gè)項(xiàng)目,不然這種使用導(dǎo)致我們可能用混,第三方庫也只支持原生js對(duì)象。
我們需要采用一些手段來規(guī)避用混。
使用類型系統(tǒng),TypeScript或Flow。消除了Immutable流經(jīng)系統(tǒng)的精神負(fù)擔(dān)。代價(jià)是編寫風(fēng)格將顛覆式的完全不同。
隱藏有關(guān)數(shù)據(jù)結(jié)構(gòu)的詳細(xì)信息。如果您在系統(tǒng)的特定部分使用Immutable.js,請(qǐng)不要在其外部進(jìn)行任何操作直接訪問數(shù)據(jù)結(jié)構(gòu)。一個(gè)很好的例子是Redux,它是單原子app狀態(tài)。如果app狀態(tài)是Immutable.js對(duì)象,請(qǐng)不要強(qiáng)制React組件直接使用Immutable.js的API。
https://codesandbox.io/s/yq872yrlnx
真正的結(jié)構(gòu)共享vs對(duì)象代理的偽實(shí)現(xiàn)
結(jié)構(gòu)共享是指沒有改變的數(shù)據(jù)共用一個(gè)引用,這樣既減少了深拷貝的性能消耗,也減少了內(nèi)存。
extend https://reactjs.org/docs/update.html
Part03 怎么用 與React搭配使用,關(guān)鍵點(diǎn)是shouldComponentUpdate熟悉 React 的都知道,React 做性能優(yōu)化時(shí)有一個(gè)避免重復(fù)渲染的大招,就是使用?shouldComponentUpdate(),但它默認(rèn)返回?true,即始終會(huì)執(zhí)行?render()?方法,然后做 Virtual DOM 比較,并得出是否需要做真實(shí) DOM 更新,盡管React的虛擬算法復(fù)雜度已經(jīng)有了很多優(yōu)化,但是在大規(guī)模組件更新時(shí),依然會(huì)是個(gè)不必要的損耗。會(huì)帶來很多無必要的渲染并成為性能瓶頸。
我們常用的Purecomponent的秘密其實(shí)是在shouldComponentUpdate中做了前后state和props的淺比較,如果不小心組件props的引用問題,這里會(huì)導(dǎo)致出現(xiàn)很多Bug。
雖然第一層數(shù)據(jù)沒變,但引用變了,就會(huì)造成虛擬?DOM?計(jì)算的浪費(fèi)。
第一層數(shù)據(jù)改變,但引用沒變,會(huì)造成不渲染,所以需要很小心的操作數(shù)據(jù)。
Object.freeze防止對(duì)象被修改
https://developer.mozilla.org...
function makeImmutable(obj, bannedMethods) { // 在對(duì)象上打上immutabilityTag標(biāo)記即表示對(duì)象不可變 addImmutabilityTag(obj); if (process.env.NODE_ENV !== "production") { // 讓所有導(dǎo)致對(duì)象改變的方法在調(diào)用時(shí)拋出錯(cuò)誤 for (var index in bannedMethods) { if (bannedMethods.hasOwnProperty(index)) { banProperty(obj, bannedMethods[index]); } } // 凍結(jié)對(duì)象 Object.freeze(obj); } return obj; }
確保對(duì)象不可變的分三步:
打上immutabilityTag標(biāo)記;
禁用會(huì)導(dǎo)致對(duì)象改變的方法;
凍結(jié)對(duì)象。
Immutable-js精讀 Immutable 結(jié)構(gòu)共享 https://juejin.im/entry/59b5e...
深入探究Immutable.js的實(shí)現(xiàn)機(jī)制 https://juejin.im/post/5b9b30...
了解Clojure的持久變量 https://hypirion.com/musings/...
完結(jié)(此文由PPT摘抄完成)PPT鏈接
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/99801.html
摘要:修改的節(jié)點(diǎn)和該父級(jí)鏈路上都變成新的對(duì)象顯然是最優(yōu)方案。如果你對(duì)比的兩個(gè)中,一個(gè)被過,另一個(gè)數(shù)據(jù)又是由其衍生出來的,那效率將是最高的算法的原理與優(yōu)化檢測(cè)本地中是否存在已過當(dāng)前對(duì)象字符串。 Immutable原理解析 簡(jiǎn)介 what is Immutable 1.不可變,一成不變的 2.對(duì)immutable數(shù)據(jù)的每次修改操作都會(huì)返回一個(gè)新的data 掏出一副老生常談的圖 showImg(h...
摘要:的優(yōu)勢(shì)保證不可變每次通過操作的對(duì)象都會(huì)返回一個(gè)新的對(duì)象豐富的性能好通過字典樹對(duì)數(shù)據(jù)結(jié)構(gòu)的共享的問題與原生交互不友好通過生成的對(duì)象在操作上與原生不同,如訪問屬性,。 Immutable.js Immutable的優(yōu)勢(shì) 1. 保證不可變(每次通過Immutable.js操作的對(duì)象都會(huì)返回一個(gè)新的對(duì)象) 2. 豐富的API 3. 性能好 (通過字典樹對(duì)數(shù)據(jù)結(jié)構(gòu)的共享) Immutab...
摘要:原文地址什么是是指一旦被創(chuàng)建就不可以被改變的數(shù)據(jù),通過使用不可變數(shù)據(jù)可以讓我們很方便的去處理數(shù)據(jù)的狀態(tài)變化檢測(cè)等問題,而且讓我們的程序變得更加的可預(yù)見怎么用大體使用深度轉(zhuǎn)換和為和淺轉(zhuǎn)換給倒數(shù)第一個(gè)賦值更多可以查看這里為什么要用其實(shí)從上面 原文地址:https://gmiam.com/post/react-... 什么是 Immutable Data ? Immutable Data 是...
摘要:是開發(fā)的不可變數(shù)據(jù)集合。微信小程序無法直接使用進(jìn)行調(diào)用需要對(duì)下載的代碼進(jìn)行修改才能使用。原因分析使用了模塊化規(guī)范的實(shí)現(xiàn)很簡(jiǎn)單,先判斷是否支持模塊規(guī)范,存在則使用方式加載模塊。通過測(cè)試,微信小程序運(yùn)行環(huán)境并沒有定義。 Immutable 是 Facebook 開發(fā)的不可變數(shù)據(jù)集合。不可變數(shù)據(jù)一旦創(chuàng)建就不能被修改,是的應(yīng)用開發(fā)更簡(jiǎn)單,允許使用函數(shù)式編程技術(shù),比如惰性評(píng)估。Immutable...
摘要:這篇文章是一些操作的整理目前只有基本的操作文檔請(qǐng)查看使用過程中遇到的寫法我會(huì)不會(huì)增加在后邊當(dāng)中不可變數(shù)據(jù)有點(diǎn)不適應(yīng)需要借鑒一些中的內(nèi)容更新六月份到十月份我們完成了不可變數(shù)據(jù)的重構(gòu)配合簡(jiǎn)聊的巨大的單一可以整理出來一些常用的方法示例代碼用的是 這篇文章是 immutable-js 一些操作的整理, 目前只有基本的操作:文檔請(qǐng)查看: http://facebook.github.io/imm...
閱讀 1938·2021-09-23 11:21
閱讀 1725·2019-08-29 17:27
閱讀 1074·2019-08-29 17:03
閱讀 742·2019-08-29 15:07
閱讀 1965·2019-08-29 11:13
閱讀 2400·2019-08-26 12:14
閱讀 956·2019-08-26 11:52
閱讀 1752·2019-08-23 17:09