直接使用dom進行操作時排版與重繪的效率低,速度慢。例如插入乙個dom元素,元素本身或者繼承很多屬性,還需要註冊很多方法,導致乙個建立乙個簡單的dom也要消耗很多時間。虛擬dom是在首次渲染dom時,多了一層虛擬dom的計算,在dom的基礎上建立了乙個抽象層。當有改動時,會生成乙個新的虛擬dom與上一次生成的虛擬dom去diff,得到乙個差異化的部分patch,最後將patch打到瀏覽器的dom上去。
兩個樹的完全的diff演算法是乙個時間複雜度為 o(n3) 的問題。 但是在前端中,你會很少跨層地移動dom元素,所以真實的dom演算法會對同乙個層級的元素進行對比。div只會和同一層級的div對比,第二層級的只會和第二層級對比。 這樣演算法複雜度就可以達到o(n)。
三個策略
1. tree diff 層級
dom節點跨層級的移動操作特別少,可以忽略不計
對數進行分層比較,兩棵樹只會對同一層次的節點進行比較
如果出現了 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值發生改變 。
React 中的虛擬DOM
react 的重新渲染,效能是很高的。因為它引入了虛擬dom的概念。呃,來看一下,render 函式渲染頁面的幾種做法。前兩步都是拿到state 資料 與 jsx模版。第一種就是比較樸素的方式。第二種方式雖然不用完全替換,但是也需要比對兩個dom。第三種是虛擬dom方式。虛擬dom 本質上就是 js...
react中的虛擬DOM
資料驅動原理 用虛擬dom 1.state資料 2.jsx模板 3.資料 模板相結合,生成虛擬dom 虛擬dom就是乙個js物件,用它來描述真實的dom div span hello 損耗了極小的效能 4.用虛擬dom的結構生成真實的domhello 5.state 發生變化 6.資料 模板 生成新...
React中的虛擬DOM和diff演算法
react原理 我們來想一下如何實現react 第一種方案 1.state 資料 2.jsx 模板 3.資料 模板 結合,生成真實的dom 來顯示 4.state 發生改變 5.資料 模板 結合,生成真實的dom 替換原始的dom 但這種方案在第五步有著很大的效能缺陷 用新生成的dom去替換原始的d...