怎樣使用React虛擬DOM

這次給大家帶來怎樣使用React虛擬DOM,使用React虛擬DOM的注意事項有哪些,下面就是實戰案例,一起來看一下。愛掏網 - it200.com

在Web開發中,需要將數據的變化實時反映到UI上,這時就需要對DOM進行操作,但是復雜或頻繁的DOM操作通常是性能瓶頸產生的原因,為此,React引入了虛擬DOM(Virtual DOM)的機制。愛掏網 - it200.com

一、什么是虛擬DOM?

在React中,render執行的結果得到的并不是真正的DOM節點,結果僅僅是輕量級的JavaScript對象,我們稱之為virtual DOM。愛掏網 - it200.com

虛擬DOM是React的一大亮點,具有batching(批處理)和高效的Diff算法。愛掏網 - it200.com這讓我們可以無需擔心性能問題而”毫無顧忌”的隨時“刷新”整個頁面,由虛擬 DOM來確保只對界面上真正變化的部分進行實際的DOM操作。愛掏網 - it200.com在實際開發中基本無需關心虛擬DOM是如何運作的,但是理解其運行機制不僅有助于更好的理解React組件的生命周期,而且對于進一步優化 React程序也會有很大幫助。愛掏網 - it200.com

二、虛擬DOM VS 直接操作原生DOM?

如果沒有 Virtual DOM,簡單來說就是直接重置 innerHTML。愛掏網 - it200.com這樣操作,在一個大型列表所有數據都變了的情況下,還算是合理,但是,當只有一行數據發生變化時,它也需要重置整個 innerHTML,這時候顯然就造成了大量浪費。愛掏網 - it200.com

比較innerHTML 和Virtual DOM 的重繪過程如下:

innerHTML: render html string + 重新創建所有 DOM 元素

Virtual DOM: render Virtual DOM + diff + 必要的 DOM 更新

和 DOM 操作比起來,js 計算是非常便宜的。愛掏網 - it200.comVirtual DOM render + diff 顯然比渲染 html 字符串要慢,但是,它依然是純 js 層面的計算,比起后面的 DOM 操作來說,依然便宜了太多。愛掏網 - it200.com當然,曾有人做過驗證說React的性能不如直接操作真實DOM,代碼如下:

function?Raw()?{
??var?data?=?_buildData(),
????html?=?"";
??...
??for(var?i=0;?i登錄后復制

該測試用例中雖然構造了一個包含1000個Tag的String,并把它添加到DOM樹中,但是只做了一次DOM操作。愛掏網 - it200.com然而,在實際開發過程中,這1000個元素更新可能分布在20個邏輯塊中,每個邏輯塊中包含50個元素,當頁面需要更新時,都會引起DOM樹的更新,上述代碼就近似變成了如下格式:

function Raw() {
  var data = _buildData(), 
    html = ""; 
  ... 
  for(var i=0; i登錄后復制

這樣來看,React的性能就遠勝于原生DOM操作了。愛掏網 - it200.com

而且,DOM 完全不屬于Javascript (也不在Javascript 引擎中存在).。愛掏網 - it200.comJavascript 其實是一個非常獨立的引擎,DOM其實是瀏覽器引出的一組讓Javascript操作HTML文檔的API而已。愛掏網 - it200.com在即時編譯的時代,調用DOM的開銷是很大的。愛掏網 - it200.com而Virtual DOM的執行完全都在Javascript 引擎中,完全不會有這個開銷。愛掏網 - it200.com

React.js 相對于直接操作原生DOM有很大的性能優勢, 很大程度上都要歸功于virtual DOM的batching 和diff。愛掏網 - it200.combatching把所有的DOM操作搜集起來,一次性提交給真實的DOM。愛掏網 - it200.comdiff算法時間復雜度也從標準的的Diff算法的O(n^3)降到了O(n)。愛掏網 - it200.com這里留到下一次博客單獨講。愛掏網 - it200.com

三、虛擬DOM VS MVVM?

相比起 React,其他 MVVM 系框架比如 Angular, Knockout 以及 Vue、Avalon 采用的都是數據綁定:通過 Directive/Binding 對象,觀察數據變化并保留對實際 DOM 元素的引用,當有數據變化時進行對應的操作。愛掏網 - it200.comMVVM 的變化檢查是數據層面的,而 React 的檢查是 DOM 結構層面的。愛掏網 - it200.comMVVM 的性能也根據變動檢測的實現原理有所不同:Angular 的臟檢查使得任何變動都有固定的 O(watcher count) 的代價;Knockout/Vue/Avalon 都采用了依賴收集,在 js 和 DOM 層面都是 O(change):

  1. 臟檢查:scope digest + 必要 DOM 更新

  2. 依賴收集:重新收集依賴 + 必要 DOM 更新

可以看到,Angular 最不效率的地方在于任何小變動都有的和 watcher 數量相關的性能代價。愛掏網 - it200.com但是!當所有數據都變了的時候,Angular 其實并不吃虧。愛掏網 - it200.com依賴收集在初始化和數據變化的時候都需要重新收集依賴,這個代價在小量更新的時候幾乎可以忽略,但在數據量龐大的時候也會產生一定的消耗。愛掏網 - it200.com

MVVM 渲染列表的時候,由于每一行都有自己的數據作用域,所以通常都是每一行有一個對應的 ViewModel 實例,或者是一個稍微輕量一些的利用原型繼承的 "scope" 對象,但也有一定的代價。愛掏網 - it200.com所以,MVVM 列表渲染的初始化幾乎一定比 React 慢,因為創建 ViewModel / scope 實例比起 Virtual DOM 來說要昂貴很多。愛掏網 - it200.com這里所有 MVVM 實現的一個共同問題就是在列表渲染的數據源變動時,尤其是當數據是全新的對象時,如何有效地復用已經創建的 ViewModel 實例和 DOM 元素。愛掏網 - it200.com假如沒有任何復用方面的優化,由于數據是 “全新” 的,MVVM 實際上需要銷毀之前的所有實例,重新創建所有實例,最后再進行一次渲染!這就是為什么題目里鏈接的 angular/knockout 實現都相對比較慢。愛掏網 - it200.com相比之下,React 的變動檢查由于是 DOM 結構層面的,即使是全新的數據,只要最后渲染結果沒變,那么就不需要做無用功。愛掏網 - it200.com

Angular 和 Vue 都提供了列表重繪的優化機制,也就是 “提示” 框架如何有效地復用實例和 DOM 元素。愛掏網 - it200.com比如數據庫里的同一個對象,在兩次前端 API 調用里面會成為不同的對象,但是它們依然有一樣的 uid。愛掏網 - it200.com這時候你就可以提示 track by uid 來讓 Angular 知道,這兩個對象其實是同一份數據。愛掏網 - it200.com那么原來這份數據對應的實例和 DOM 元素都可以復用,只需要更新變動了的部分。愛掏網 - it200.com或者,你也可以直接 track by $index 來進行 “原地復用”:直接根據在數組里的位置進行復用。愛掏網 - it200.com在題目給出的例子里,如果 angular 實現加上 track by $index 的話,后續重繪是不會比 React 慢多少的。愛掏網 - it200.com甚至在 dbmonster 測試中,Angular 和 Vue 用了 track by $index 以后都比 React 快: dbmon (注意 Angular 默認版本無優化,優化過的在下面)

在比較性能的時候,要分清楚初始渲染、小量數據更新、大量數據更新這些不同的場合。愛掏網 - it200.comVirtual DOM、臟檢查 MVVM、數據收集 MVVM 在不同場合各有不同的表現和不同的優化需求。愛掏網 - it200.comVirtual DOM 為了提升小量數據更新時的性能,也需要針對性的優化,比如 shouldComponentUpdate 或是 immutable data。愛掏網 - it200.com

  1. 初始渲染:Virtual DOM > 臟檢查 >= 依賴收集

  2. 小量數據更新:依賴收集 >> Virtual DOM + 優化 > 臟檢查(無法優化) > Virtual DOM 無優化

  3. 大量數據更新:臟檢查 + 優化 >= 依賴收集 + 優化 > Virtual DOM(無法/無需優化)>> MVVM 無優化

  4. (該段落借鑒了知乎的相關回答)

  5. 四、對React虛擬DOM的誤解?

    React 從來沒有說過 “React 比原生操作 DOM 快”。愛掏網 - it200.comReact給我們的保證是,在不需要手動優化的情況下,它依然可以給我們提供過得去的性能。愛掏網 - it200.com

    React掩蓋了底層的 DOM 操作,可以用更聲明式的方式來描述我們目的,從而讓代碼更容易維護。愛掏網 - it200.com下面還是借鑒了知乎上的回答:沒有任何框架可以比純手動的優化 DOM 操作更快,因為框架的 DOM 操作層需要應對任何上層 API 可能產生的操作,它的實現必須是普適的。愛掏網 - it200.com針對任何一個 benchmark,我都可以寫出比任何框架更快的手動優化,但是那有什么意義呢?在構建一個實際應用的時候,你難道為每一個地方都去做手動優化嗎?出于可維護性的考慮,這顯然不可能。愛掏網 - it200.com

    相信看了本文案例你已經掌握了方法,更多精彩請關注愛掏網 - it200.com其它相關文章!

    推薦閱讀:

    微信小程序內實現上傳圖片附后端代碼

    微信小程序上傳圖片實戰案例解析

    以上就是怎樣使用React虛擬DOM的詳細內容,更多請關注愛掏網 - it200.com其它相關文章!

聲明:所有內容來自互聯網搜索結果,不保證100%準確性,僅供參考。如若本站內容侵犯了原著者的合法權益,可聯系我們進行處理。
發表評論
更多 網友評論0 條評論)
暫無評論

返回頂部

主站蜘蛛池模板: 依依成人精品视频在线观看| 国产精品自产拍在线观看| 伊人色综合久久88加勒| 国产自产视频在线观看香蕉| 日韩欧美中文字幕一区二区三区| 免费成人在线电影| 91九色精品国产免费| 欧美videosdesexo肥婆| 动漫精品专区一区二区三区不卡| aaa一级最新毛片| 日本午夜大片a在线观看| 又粗又大又黄又硬又爽毛片| 亚洲综合校园春色| 女皇跪趴受辱娇躯| 亚洲人在线视频| 秋葵app官网免费下载地址| 国产成在线观看免费视频| 中文乱码字字幕在线第5页| 欧美一级在线播放| 啊啊啊好大好爽视频| 91久久国产精品| 成人综合国产乱在线| 亚洲AV无码一区二区一二区| 波多野结衣中文在线播放| 国产CHINESE男男GAYGAY网站| 婷婷丁香六月天| 工棚里的换爱系列小说| 亚洲国产一区二区三区在线观看 | 精品视频九九九| 国产高清自产拍av在线| 三级在线看中文字幕完整版| 日韩大片高清播放器| 亚洲婷婷第一狠人综合精品| 西西人体www高清大胆视频| 国产精品久久久久久久久久免费 | 在线视频免费观看www动漫| 亚洲av午夜国产精品无码中文字| 美女极度色诱视频国产| 国产自无码视频在线观看| 久久久无码精品亚洲日韩蜜桃 | 久久久久99精品成人片欧美|