解析 React 虛擬 DOM 原理 + DOM Diff 算法

導讀:

  • 當用原生 JS / jQuery 操作 DOM 時,瀏覽器會從構建 DOM 樹開始從頭到尾渲染一遍 DOM 節點,而大量的 DOM 操作會頻繁的更新 DOM( 即再次從頭到尾渲染 ),這無疑是非常消耗瀏覽器性能的,因此由 FaceBook 團隊提出的虛擬 DOM 橫空出世,并運用在了 React 之上( 目前 Vue 2.x 也引入了這個概念 ),接下來我們就分析一下虛擬 DOM 的原理。

虛擬 DOM 原理:

  • 無虛擬 DOM 時,React 中 DOM 的渲染流程:
    1. state 數據
    2. JSX 模板
    3. 數據 + 模板 結合,生成真實的 DOM,來顯示
    4. state 發生改變
    5. 數據 + 模板 結合,生成真實的 DOM,替換原始的 DOM

缺陷:
第一次生成了一個完整的 DOM 片段
第二次生成了一個完整的 DOM 片段
第二次的 DOM 替換了第一次的 DOM,非常耗性能

  • React 優化后,React 中 DOM 的渲染流程:
    1. state 數據
    2. JSX 模板
    3. 數據 + 模板 結合,生成真實的 DOM,來顯示
    4. state 發生改變
    5. 數據 + 模板 結合,生成真實的 DOM,并不直接替換原始的 DOM
    6. 新的 DOM( DocumentFragment )和原來的 DOM 樹做對比,找差異( 耗性能 )
    7. 找出發生變化的節點
    8. 只能新的 DOM 中發生變化的節點替換掉老的 DOM 中的相應節點

缺陷:
性能提升并不明顯

  • 引入虛擬 DOM 后,React 中 DOM 的渲染流程:
    1. state 數據
    2. JSX 模板
    3. 數據 + 模板,生成虛擬 DOM ( 虛擬 DOM 就是一個 JS 對象,用它來描述真實的 DOM )( 損耗了性能 )
      [ 'div', { id: "root" }, [ 'span', { }, 'hello world' ] ]
    4. 用虛擬 DOM 的結構生成真實的 DOM,來顯示
      <div id="root"><span>hello world</span></div>
    5. state 發生變化
    6. 數據 + 模板 結合,生成新的虛擬 DOM( 極大提升了性能 )
      [ 'div', { id: "root" }, [ 'span', { }, 'bye bye' ] ]
    7. 比較新的虛擬 DOM 和原始虛擬 DOM 的區別,找到區別是 span 中的內容( 極大提升了性能 )
    8. 直接操作 DOM,改變 span 中的內容
      總結:JSX -> React.createElement -> 虛擬 DOM (JS對象)-> 真實的DOM

優點:
性能提升
它使得跨端應用得以實現。React Native

DOM Diff 算法:

  • 首先當改變 state 數據時,由于 setState 是一個異步函數( 官方文檔原話:不保證它是同步的 ),這里關于異步的問題我們暫時這么理解,如果深究可以自行去其他博客學習,當你一次調用三次 setState 時,React 并不會生成三次虛擬 DOM 而是將三次 setState 合并,然后生成一次虛擬 DOM 進行比對,接下來:


  • 當新的虛擬 DOM 與原來的虛擬 DOM 進行比對時,它會進行同層比較,即相同的節點層進行比較,如果不同則直接將原始虛擬 DOM 中該節點層及以下的節點全部刪除,重新生成新的虛擬 DOM 節點,而不會繼續向下比對。


  • 這里順便提一點,當你在 JSX 模板中遍歷 state 中某個數據時,為什么不加 key 值瀏覽器會報錯,這是因為你不再遍歷的每條數據加上 key 值,更改 state 中那條數據的值,生成虛擬 DOM 后,React 就不知道原始遍歷的數據和這次更新后遍歷的數據一一對應的關系,就會再次重新渲染,而加上 key 值,它則能迅速比對出有差異的部分進行部分的更新,但是為什么不建議用 index 作為 key 值呢?因為當你插入 / 刪除中間的數據時,從改變的那個數據開始,后續每個數據的 index 值就會變,從而就導致了每個數據的 key 值相應變化了,這樣依舊會引起大規模渲染,這就是其中的原因啦。


總結:

  • 這篇文章真的干貨滿滿,上面的內容都是博主精心總結的,建議各位讀者細讀,必有大收獲!
  • Vue 2.x 的虛擬 DOM 原理和 DOM Diff算法與 React 的基本大同小異,一篇懂,全都懂!
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容