什麼是虛擬dom?
這就要從react如何渲染出頁面開始 通常情況下的步驟是這樣
- 獲取state資料
- JSX模板
- state+JSX模板結合,生成真實dom並顯示
這個是在state不發生變化的情況下,(state或者prop發生變化都會呼叫render函式,重新渲染頁面)
state資料變化時,通常理解下應該是下面的步驟
- 獲取state資料
- JSX模板
- state資料+JSX模板結合,生成真實dom並顯示
- state資料發生變化
- 新的state資料+JSX模板結合,生成真實dom並顯示
這樣可以實現,但是非常消耗效能,因為會渲染兩次dom樹,所以react就採用一種虛擬dom的方法來進行dom更新。
JSX轉成dom流程
用JSX語法時,渲染dom的流程:JSX——JS dom描述物件——真實dom
具體步驟:
- 獲取state資料
- JSX模板
- 生成虛擬dom(虛擬dom就是一個JS物件,裡面包含了對真實dom的描述
['div',{id:'a'},['span',{},'hello']]
複製程式碼
- 用虛擬dom解構,生成真實dom並顯示
<div id='a'><span>hello</span></div>
複製程式碼
- state資料發生變化(比如hello變成了hi)
- 生成新的虛擬dom
['div',{id:'a'},['span',{},'hi']]
複製程式碼
- 比較原始虛擬dom和新的虛擬dom的區別,找出區別是span裡的內容
- 直接操作dom,只改變span裡的內容
虛擬dom的好處
- 效能提升,dom比對變成js物件比對
- 使得跨端應用得以實現(react native)
在瀏覽器中可以用虛擬dom生成真實dom顯示,在原生應用中也可以用虛擬dom生成對應的方式來顯示頁面
虛擬dom中的diff演算法
在上面我們介紹了react中state變化時,dom是如何發生變化的,在第七步中比較原始虛擬dom和新的虛擬dom的區別採用的方法,就是diff演算法(diffrence)
虛擬dom在什麼時候會發生比對?沒錯,資料發生變化時,也就是呼叫setState時
react的虛擬dom其實是同級比較的
如上圖 他的對比步驟如下- 紅色原始虛擬dom和新的虛擬dom,沒有變化,保持不變,往下繼續比對
- 藍色原始虛擬dom和新的虛擬dom,沒有變化,保持不變,往下繼續比對
- 綠色原始虛擬dom和新的虛擬dom,沒有變化,保持不變,往下繼續比對,淺藍色原始虛擬dom和新的虛擬dom,沒有變化,保持不變,往下繼續比對
但凡在上面哪一步驟出現不同,就不再繼續比對,而是刪除下面的全部節點,採用新的虛擬dom(例如:如果紅色框的原始虛擬dom和新的虛擬dom不一致,那麼就不在進行比對,採用新的虛擬dom來生成dom)
key的作用
react利用key來識別元件,它是一種身份標識標識,來提高虛擬dom的比對速度看下面
比如我要在abcde中新增一個f如果我們沒有key值,那我們就需要A比對一遍,B對比一遍,以此類推很好效能,而有了key,就像下面的圖一樣,我們很快就知道只有f與之前不同,提高了列表渲染的效能