在Web開發中,需要將數據的變化實時反映到UI上,這時就需要對DOM進行操作,但是復雜或頻繁的DOM操作通常是性能瓶頸產生的原因,為此,React引入了虛擬DOM(Virtual DOM)的機制。
一、什么是虛擬DOM?
在React中,render執行的結果得到的并不是真正的DOM節點,結果僅僅是輕量級的JavaScript對象,我們稱之為virtual DOM。
虛擬DOM是React的一大亮點,具有batching(批處理)和高效的Diff算法。這讓我們可以無需擔心性能問題而”毫無顧忌”的隨時“刷新”整個頁面,由虛擬 DOM來確保只對界面上真正變化的部分進行實際的DOM操作。在實際開發中基本無需關心虛擬DOM是如何運作的,但是理解其運行機制不僅有助于更好的理解React組件的生命周期,而且對于進一步優化 React程序也會有很大幫助。
二、虛擬DOM VS 直接操作原生DOM?
如果沒有 Virtual DOM,簡單來說就是直接重置 innerHTML。這樣操作,在一個大型列表所有數據都變了的情況下,還算是合理,但是,當只有一行數據發生變化時,它也需要重置整個 innerHTML,這時候顯然就造成了大量浪費。
比較innerHTML 和Virtual DOM 的重繪過程如下:
innerHTML: render html string + 重新創建所有 DOM 元素
Virtual DOM: render Virtual DOM + diff + 必要的 DOM 更新
和 DOM 操作比起來,js 計算是非常便宜的。Virtual DOM render + diff 顯然比渲染 html 字符串要慢,但是,它依然是純 js 層面的計算,比起后面的 DOM 操作來說,依然便宜了太多。當然,曾有人做過驗證說React的性能不如直接操作真實DOM,代碼如下:
function Raw() { var data = _buildData(), html = ""; ... for(var i=0; i<data.length; i++) { var render = template; render = render.replace("{{className}}", ""); render = render.replace("{{label}}", data[i].label); html += render; } ... container.innerHTML = html; ...}該測試用例中雖然構造了一個包含1000個Tag的String,并把它添加到DOM樹中,但是只做了一次DOM操作。然而,在實際開發過程中,這1000個元素更新可能分布在20個邏輯塊中,每個邏輯塊中包含50個元素,當頁面需要更新時,都會引起DOM樹的更新,上述代碼就近似變成了如下格式:
function Raw() { var data = _buildData(), html = ""; ... for(var i=0; i<data.length; i++) { var render = template; render = render.replace("{{className}}", ""); render = render.replace("{{label}}", data[i].label); html += render; if(!(i % 50)) { container.innerHTML = html; } } ... }這樣來看,React的性能就遠勝于原生DOM操作了。
而且,DOM 完全不屬于Javascript (也不在Javascript 引擎中存在).。Javascript 其實是一個非常獨立的引擎,DOM其實是瀏覽器引出的一組讓Javascript操作HTML文檔的API而已。在即時編譯的時代,調用DOM的開銷是很大的。而Virtual DOM的執行完全都在Javascript 引擎中,完全不會有這個開銷。
新聞熱點
疑難解答
圖片精選