React Diff算法
diff算法,是虛擬DOM產(chǎn)生的一個概念,用來計算出虛擬DOM中真正變化的部分,并只針對該部分進行原生DOM操作,而非重新渲染整個頁面,從而提高了頁面的渲染效率。
一、它的作用是什么?
- 渲染真實DOM的開銷很大,有時候我們修改某個數(shù)據(jù)時,直接渲染到真實DOM上會引起整個DOM樹的重繪和重排。我們希望只更新我們該的那么一小塊DOM,而不是整個DOM,diff算法就幫我們實現(xiàn)了這一點。
diff算法本質(zhì)就是:找出兩個對象之間的差異,目的是盡可能做到節(jié)點復(fù)用。
二、React的Diff算法
1.了解一下什么是調(diào)和?
將virtualDOM(虛擬DOM)轉(zhuǎn)換成actualDOM(真實DOM)的最少操作過程就叫調(diào)和,簡單理解就是簡化算法復(fù)雜度。
2.react的diff算法
react的diff算法就是實現(xiàn)了上述的調(diào)和,簡化了算法的復(fù)雜度。
3.React Diff的三大策略
react用tree diff(樹比較)、component diff(組件比較)、element diff(元素比較)三大策略將O(n^3)的復(fù)雜度轉(zhuǎn)化為O(n)的復(fù)雜度
(1) 策略一(tree diff):Web UI中DOM節(jié)點跨層級的移動操作特別少,可以忽略不計。
(2) 策略二(component diff):擁有相同類的兩個組件生成相似的樹形結(jié)構(gòu),擁有不同類的兩個組件生成不同的樹形結(jié)構(gòu)。
(3) 策略三(element diff):對于同一層級的一組子節(jié)點,通過唯一id區(qū)分。
4.tree diff:
(1) React通過updateDepth對比Virtual DOM樹進行層級控制。
(2) 對樹分層比較,兩顆樹只對同一層次節(jié)點進行比較。如果該節(jié)點不存在時,則該節(jié)點及其子節(jié)點會被完全刪除,不會再進一步比較。
(3) 只需遍歷一次,就能完成整顆DOM樹的比較。
1、如果DOM節(jié)點出現(xiàn)了跨層級操作,Diff會怎么辦?
Tree Diff是對樹的每一層進行遍歷,如果某組件不存在了,則會直接銷毀。
5. component diff:
(1) 同一類型的兩個組件,按原策略(層級比較)繼續(xù)比較Virtual DOM樹即可。
(2) 同一類型的兩個組件,組件A變化為組件B時,可能Virtual DOM沒有任何變化,如果知道這點,可節(jié)省大量計算時間,所以用戶可以通過shouldComponentUpdate()來判斷是否需要判斷計算。
(3) 不同類型的組件,將一個組件判斷為dirtycomponent(臟組件),從而替換整個組件的所有節(jié)點。
注意:如上圖所示,當(dāng)組件D變?yōu)榻M件G時,即使這兩個組件結(jié)構(gòu)相似,一旦React判斷D和G是不用類型的組件,就不會比較兩者的結(jié)構(gòu),而是直接刪除組件D,重新創(chuàng)建組件G及其子節(jié)點。雖然當(dāng)兩個組件是不同類型但結(jié)構(gòu)相似時,進行diff算法分析會影響性能,但是畢竟不同類型的組件存在相似DOM樹的情況在實際開發(fā)過程中很少出現(xiàn),因此這種極端因素很難在實際開發(fā)過程中造成重大影響。
6. element diff:
當(dāng)節(jié)點處于同一層級時,diff提供三種節(jié)點操作:刪除、插入、移動。
插入:組件C不在集合(A,B)中,需要插入。
刪除:
- 組件D在集合(A,B,D)中,但D的節(jié)點已經(jīng)更改,不能復(fù)用和更新,所以需要刪除舊的D,再創(chuàng)建新的。
- 組件D之前在集合(A,B.D)中,但集合變成新的集合(A,B)了,D就需要被刪除。
移動:組件D已經(jīng)在集合(A,B,C,D)里了,且集合更新時,D沒有發(fā)生更新,只是位置改變,如新集合(A,D,B,C),D在第二個,無需像傳統(tǒng)DIFF,讓就集合的第二個B和新集合的第二個D比較,并且刪除第二個位置的B,在第二個位置插入D,而是添加唯一key進行區(qū)分,移動即可。
(1)B不移動,不贅述,更新l astIndex=1
(2)新集合取得 E,發(fā)現(xiàn)舊不存在,故在lastIndex=1的位置 創(chuàng)建E,更新lastIndex=1
(3)新集合取得C,C不移動,更新lastIndex=2
(4)新集合取得A,A移動,同上,更新lastIndex=2
(5)新集合對比后,再對舊集合遍歷。判斷 新集合 沒有,但 舊集合 有的元素(如D,新集合沒有,舊集合有),發(fā)現(xiàn) D,刪除D,diff操作結(jié)束。
6. element diff:
基于tree diff:
- 開發(fā)組件時,注意保持DOM結(jié)構(gòu)的穩(wěn)定;即,盡可能少地動態(tài)操作DOM結(jié)構(gòu),尤其是移動操作。
- 當(dāng)節(jié)點數(shù)過大或者頁面更新次數(shù)過多時,頁面卡頓的現(xiàn)象會比較明顯。
- 這時可以通過 CSS 隱藏或顯示節(jié)點,而不是真的移除或添加 DOM 節(jié)點。
基于component diff:
- 注意使用 shouldComponentUpdate() 來減少組件不必要的更新。
- 對于類似的結(jié)構(gòu)應(yīng)該盡量封裝成組件,既減少代碼量,又能減少component diff的性能消耗。
基于element diff:文章來源:http://www.zghlxwxcb.cn/news/detail-672086.html
- 對于列表結(jié)構(gòu),盡量減少類似將最后一個節(jié)點移動到列表首部的操作,當(dāng)節(jié)點數(shù)量過大或更新操作過于頻繁時,在一定程度上會影響 React 的渲染性能。
總結(jié)
提示:這里對文章進行總結(jié):
例如:以上就是今天要講的內(nèi)容,本文僅僅簡單介紹了pandas的使用,而pandas提供了大量能使我們快速便捷地處理數(shù)據(jù)的函數(shù)和方法。文章來源地址http://www.zghlxwxcb.cn/news/detail-672086.html
到了這里,關(guān)于React Diff算法的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!