React虛擬dom和diff演算法

Little heaven發表於2019-01-30

什麼是虛擬dom?

這就要從react如何渲染出頁面開始 通常情況下的步驟是這樣

  1. 獲取state資料
  2. JSX模板
  3. state+JSX模板結合,生成真實dom並顯示

這個是在state不發生變化的情況下,(state或者prop發生變化都會呼叫render函式,重新渲染頁面)

state資料變化時,通常理解下應該是下面的步驟

  1. 獲取state資料
  2. JSX模板
  3. state資料+JSX模板結合,生成真實dom並顯示
  4. state資料發生變化
  5. 新的state資料+JSX模板結合,生成真實dom並顯示

這樣可以實現,但是非常消耗效能,因為會渲染兩次dom樹,所以react就採用一種虛擬dom的方法來進行dom更新。

JSX轉成dom流程

用JSX語法時,渲染dom的流程:JSX——JS dom描述物件——真實dom

具體步驟:

  1. 獲取state資料
  2. JSX模板
  3. 生成虛擬dom(虛擬dom就是一個JS物件,裡面包含了對真實dom的描述
['div',{id:'a'},['span',{},'hello']]
複製程式碼
  1. 用虛擬dom解構,生成真實dom並顯示
<div id='a'><span>hello</span></div>
複製程式碼
  1. state資料發生變化(比如hello變成了hi)
  2. 生成新的虛擬dom
['div',{id:'a'},['span',{},'hi']]
複製程式碼
  1. 比較原始虛擬dom和新的虛擬dom的區別,找出區別是span裡的內容
  2. 直接操作dom,只改變span裡的內容

虛擬dom的好處

  1. 效能提升,dom比對變成js物件比對
  2. 使得跨端應用得以實現(react native)

在瀏覽器中可以用虛擬dom生成真實dom顯示,在原生應用中也可以用虛擬dom生成對應的方式來顯示頁面

虛擬dom中的diff演算法

在上面我們介紹了react中state變化時,dom是如何發生變化的,在第七步中比較原始虛擬dom和新的虛擬dom的區別採用的方法,就是diff演算法(diffrence)

虛擬dom在什麼時候會發生比對?沒錯,資料發生變化時,也就是呼叫setState時

react的虛擬dom其實是同級比較的

React虛擬dom和diff演算法
如上圖 他的對比步驟如下

  1. 紅色原始虛擬dom和新的虛擬dom,沒有變化,保持不變,往下繼續比對
  2. 藍色原始虛擬dom和新的虛擬dom,沒有變化,保持不變,往下繼續比對
  3. 綠色原始虛擬dom和新的虛擬dom,沒有變化,保持不變,往下繼續比對,淺藍色原始虛擬dom和新的虛擬dom,沒有變化,保持不變,往下繼續比對

但凡在上面哪一步驟出現不同,就不再繼續比對,而是刪除下面的全部節點,採用新的虛擬dom(例如:如果紅色框的原始虛擬dom和新的虛擬dom不一致,那麼就不在進行比對,採用新的虛擬dom來生成dom)

key的作用

react利用key來識別元件,它是一種身份標識標識,來提高虛擬dom的比對速度看下面

React虛擬dom和diff演算法
比如我要在abcde中新增一個f

如果我們沒有key值,那我們就需要A比對一遍,B對比一遍,以此類推很好效能,而有了key,就像下面的圖一樣,我們很快就知道只有f與之前不同,提高了列表渲染的效能

React虛擬dom和diff演算法

相關文章