React-爲什麼要使用虛擬DOM

什麼是虛擬DOM(Virtual DOM)

首先,解釋下虛擬DOM。虛擬DOM保存了真實DOM的層次關係和一些基本屬性,與真實DOM一一對應。虛擬DOM的工作原理是:數據 -> 全新的虛擬DOM -> 與上一個狀態的虛擬DOM進行diff算法比較,得到一個Patch -> 把這個Patch打到瀏覽器的DOM上。所以虛擬DOM叫的挺高端,其實就有點類似DocumentFragment,把多次DOM操作做一個批處理。於是,有一件很有意思的事情,如果你手動在DOM裏刪除一些節點,使得虛擬DOM與真實DOM不能一一對應了,再改變state重新render頁面,頁面就亂了。

diff算法

其次,想分享下diff算法。前兩天看司徒正美推銷他的Avalon,也分析了下React,說了一句話,現在前端框架比的是算法。diff算法說白了就是比較兩個文件不同的算法。一般diff算法的複雜度是O(n3)。Facebook工程師根據前端頁面特點做了兩個假設(如果你好奇是什麼假設這麼神奇,可以來問我),把比較前後兩個狀態虛擬DOM的diff算法的複雜度降到了O(n)。這個diff算法分爲三部分,我用三句話總結:
1. 虛擬DOM樹同一位置不同類型(標籤不同)的節點:刪除前一狀態節點,插入後一狀態節點,哪怕節點有子節點也這樣做;
2. 虛擬DOM樹同一位置相同類型但個別屬性不同的節點,對前一狀態節點進行屬性重設;
3. 列表節點(就是我們用循環創建的類似Array的節點),如果沒有unique key(沒有控制檯會報警告的)就按照前面兩種方式解決,如果有unique key就找到key相應的位置插入節點。
真的很簡單,印證了一句話,簡單的算法往往效率最高,好像我做推薦算法,單個算法不混合的話,依然是協同過濾效果最好。

虛擬DOM快在哪裏

然後,js計算肯定要比DOM操作快啊,每次DOM操作都很有可能引起迴流(Reflow)和重繪(Repaint)啊。當然瀏覽器也不傻,不是你每次操作DOM瀏覽器都重繪一次,一般瀏覽器會按照時間或次數間隔進行DOM操作的批處理。那問題來了,到底是瀏覽器優化後的DOM批處理快,還是React的虛擬DOM+優化diff算法快。這個我沒有測試過,根據博客上內容,React的優化更人性化、也更快。速度快肯定是虛擬DOM的一個優點,另外一點,瀏覽器對DOM操作批處理的主動權不在前端人員手中,React將這種批處理的時機選擇交到了我們手中,看我們什麼時候想render頁面。這個和AJAX+回調帶來的問題一樣,當我們發送一個AJAX,然後指定一個回調函數時候,對回調裏代碼的控制權就交給瀏覽器了,所以前端人員常常感覺AJAX不可控,不知道回調什麼時候執行完了,頁面一大堆flag。

發佈了82 篇原創文章 · 獲贊 82 · 訪問量 44萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章