天天看點

對react中虛拟dom和diff算法的了解虛拟dom的出現虛拟dom實作:diff算法

虛拟dom的出現

直接使用dom進行操作時排版與重繪的效率低,速度慢。例如插入一個dom元素,元素本身或者繼承很多屬性,還需要注冊很多方法,導緻一個建立一個簡單的dom也要消耗很多時間。虛拟dom是在首次渲染dom時,多了一層虛拟dom的計算,在dom的基礎上建立了一個抽象層。當有改動時,會生成一個新的虛拟dom與上一次生成的虛拟dom去diff,得到一個差異化的部分patch,最後将patch打到浏覽器的dom上去。

虛拟dom實作:diff算法

兩個樹的完全的diff算法是一個時間複雜度為 O(n3) 的問題。 但是在前端中,你會很少跨層地移動DOM元素,是以真實的DOM算法會對同一個層級的元素進行對比。div隻會和同一層級的div對比,第二層級的隻會和第二層級對比。 這樣算法複雜度就可以達到O(n)。

三個政策

1. tree diff 層級

DOM節點跨層級的移動操作特别少,可以忽略不計

對數進行分層比較,兩棵樹隻會對同一層次的節點進行比較

對react中虛拟dom和diff算法的了解虛拟dom的出現虛拟dom實作:diff算法

如果出現了 DOM 節點跨層級的移動操作,也隻會對應層級進行删除和建立。不會有移動的操作,是以盡量不用進行dom節點跨層級操作

2. component diff 元件級

擁有相同類的兩個元件會生成相似的樹形結構,不同類的兩個元件會生成不同的樹形結構

進行了tree diff之後 如果有需要更新的元件,則進行component diff對比元件的差異。

對比後,元件類型相同,則此元件不需要更新,又進行element diff進行元素級别的對比。

對比後,元件類型不同,需要移除舊元件,建立新元件

3. element diff 元素級

對于同一層級的一組子節點,可以通過唯一key區分

比較後,對于新節點插入,對于多餘的節點删除,對于換位的節點進行移動。key值的作用是,隻要判斷key值對應的元素沒有改變,隻需要執行移動。

流程:新舊節點周遊後,新節點newindex,舊節點oldindex。如果發現新集合中某節點在舊集合中也存在,于是對比兩個index,newindex大于oldindex,需要将舊節點移動到新的位置,相反則不動,找不到對應的節點,新增,最後舊節點在新節點用不上舊删除。最後一個節點移動到第一個位置,對導緻n-1個節點都進行後移,影響性能,盡量避免。

不能用 index 作為 key,當數組中的資料發生變化時: React 比較更新前後的元素 key 值,如果相同則更新。如果不同則銷毀之前的,重新建立一個元素。當以數組的下标index作為key值時,其中一個元素發生了變化 就有可能導緻所有元素的key值發生改變 。