這次給大家?guī)碓鯓邮褂肦eact虛擬DOM,使用React虛擬DOM的注意事項(xiàng)有哪些,下面就是實(shí)戰(zhàn)案例,一起來看一下。
在Web開發(fā)中,需要將數(shù)據(jù)的變化實(shí)時反映到UI上,這時就需要對DOM進(jìn)行操作,但是復(fù)雜或頻繁的DOM操作通常是性能瓶頸產(chǎn)生的原因,為此,React引入了虛擬DOM(Virtual DOM)的機(jī)制。
一、什么是虛擬DOM?
在React中,render執(zhí)行的結(jié)果得到的并不是真正的DOM節(jié)點(diǎn),結(jié)果僅僅是輕量級的JavaScript對象,我們稱之為virtual DOM。
虛擬DOM是React的一大亮點(diǎn),具有batching(批處理)和高效的Diff算法。這讓我們可以無需擔(dān)心性能問題而”毫無顧忌”的隨時“刷新”整個頁面,由虛擬 DOM來確保只對界面上真正變化的部分進(jìn)行實(shí)際的DOM操作。在實(shí)際開發(fā)中基本無需關(guān)心虛擬DOM是如何運(yùn)作的,但是理解其運(yùn)行機(jī)制不僅有助于更好的理解React組件的生命周期,而且對于進(jìn)一步優(yōu)化 React程序也會有很大幫助。
二、虛擬DOM VS 直接操作原生DOM?
如果沒有 Virtual DOM,簡單來說就是直接重置 innerHTML。這樣操作,在一個大型列表所有數(shù)據(jù)都變了的情況下,還算是合理,但是,當(dāng)只有一行數(shù)據(jù)發(fā)生變化時,它也需要重置整個 innerHTML,這時候顯然就造成了大量浪費(fèi)。
比較innerHTML 和Virtual DOM 的重繪過程如下:
innerHTML: render html string + 重新創(chuàng)建所有 DOM 元素
Virtual DOM: render Virtual DOM + diff + 必要的 DOM 更新
和 DOM 操作比起來,js 計(jì)算是非常便宜的。Virtual DOM render + diff 顯然比渲染 html 字符串要慢,但是,它依然是純 js 層面的計(jì)算,比起后面的 DOM 操作來說,依然便宜了太多。當(dāng)然,曾有人做過驗(yàn)證說React的性能不如直接操作真實(shí)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; ... }
該測試用例中雖然構(gòu)造了一個包含1000個Tag的String,并把它添加到DOM樹中,但是只做了一次DOM操作。然而,在實(shí)際開發(fā)過程中,這1000個元素更新可能分布在20個邏輯塊中,每個邏輯塊中包含50個元素,當(dāng)頁面需要更新時,都會引起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的性能就遠(yuǎn)勝于原生DOM操作了。
而且,DOM 完全不屬于Javascript (也不在Javascript 引擎中存在).。Javascript 其實(shí)是一個非常獨(dú)立的引擎,DOM其實(shí)是瀏覽器引出的一組讓Javascript操作HTML文檔的API而已。在即時編譯的時代,調(diào)用DOM的開銷是很大的。而Virtual DOM的執(zhí)行完全都在Javascript 引擎中,完全不會有這個開銷。
React.js 相對于直接操作原生DOM有很大的性能優(yōu)勢, 很大程度上都要?dú)w功于virtual DOM的batching 和diff。batching把所有的DOM操作搜集起來,一次性提交給真實(shí)的DOM。diff算法時間復(fù)雜度也從標(biāo)準(zhǔn)的的Diff算法的O(n^3)降到了O(n)。這里留到下一次博客單獨(dú)講。
三、虛擬DOM VS MVVM?
相比起 React,其他 MVVM 系框架比如 Angular, Knockout 以及 Vue、Avalon 采用的都是數(shù)據(jù)綁定:通過 Directive/Binding 對象,觀察數(shù)據(jù)變化并保留對實(shí)際 DOM 元素的引用,當(dāng)有數(shù)據(jù)變化時進(jìn)行對應(yīng)的操作。MVVM 的變化檢查是數(shù)據(jù)層面的,而 React 的檢查是 DOM 結(jié)構(gòu)層面的。MVVM 的性能也根據(jù)變動檢測的實(shí)現(xiàn)原理有所不同:Angular 的臟檢查使得任何變動都有固定的 O(watcher count) 的代價(jià);Knockout/Vue/Avalon 都采用了依賴收集,在 js 和 DOM 層面都是 O(change):
臟檢查:scope digest + 必要 DOM 更新
依賴收集:重新收集依賴 + 必要 DOM 更新
可以看到,Angular 最不效率的地方在于任何小變動都有的和 watcher 數(shù)量相關(guān)的性能代價(jià)。但是!當(dāng)所有數(shù)據(jù)都變了的時候,Angular 其實(shí)并不吃虧。依賴收集在初始化和數(shù)據(jù)變化的時候都需要重新收集依賴,這個代價(jià)在小量更新的時候幾乎可以忽略,但在數(shù)據(jù)量龐大的時候也會產(chǎn)生一定的消耗。
MVVM 渲染列表的時候,由于每一行都有自己的數(shù)據(jù)作用域,所以通常都是每一行有一個對應(yīng)的 ViewModel 實(shí)例,或者是一個稍微輕量一些的利用原型繼承的 "scope" 對象,但也有一定的代價(jià)。所以,MVVM 列表渲染的初始化幾乎一定比 React 慢,因?yàn)閯?chuàng)建 ViewModel / scope 實(shí)例比起 Virtual DOM 來說要昂貴很多。這里所有 MVVM 實(shí)現(xiàn)的一個共同問題就是在列表渲染的數(shù)據(jù)源變動時,尤其是當(dāng)數(shù)據(jù)是全新的對象時,如何有效地復(fù)用已經(jīng)創(chuàng)建的 ViewModel 實(shí)例和 DOM 元素。假如沒有任何復(fù)用方面的優(yōu)化,由于數(shù)據(jù)是 “全新” 的,MVVM 實(shí)際上需要銷毀之前的所有實(shí)例,重新創(chuàng)建所有實(shí)例,最后再進(jìn)行一次渲染!這就是為什么題目里鏈接的 angular/knockout 實(shí)現(xiàn)都相對比較慢。相比之下,React 的變動檢查由于是 DOM 結(jié)構(gòu)層面的,即使是全新的數(shù)據(jù),只要最后渲染結(jié)果沒變,那么就不需要做無用功。
Angular 和 Vue 都提供了列表重繪的優(yōu)化機(jī)制,也就是 “提示” 框架如何有效地復(fù)用實(shí)例和 DOM 元素。比如數(shù)據(jù)庫里的同一個對象,在兩次前端 API 調(diào)用里面會成為不同的對象,但是它們依然有一樣的 uid。這時候你就可以提示 track by uid 來讓 Angular 知道,這兩個對象其實(shí)是同一份數(shù)據(jù)。那么原來這份數(shù)據(jù)對應(yīng)的實(shí)例和 DOM 元素都可以復(fù)用,只需要更新變動了的部分?;蛘?,你也可以直接 track by $index 來進(jìn)行 “原地復(fù)用”:直接根據(jù)在數(shù)組里的位置進(jìn)行復(fù)用。在題目給出的例子里,如果 angular 實(shí)現(xiàn)加上 track by $index 的話,后續(xù)重繪是不會比 React 慢多少的。甚至在 dbmonster 測試中,Angular 和 Vue 用了 track by $index 以后都比 React 快: dbmon (注意 Angular 默認(rèn)版本無優(yōu)化,優(yōu)化過的在下面)
在比較性能的時候,要分清楚初始渲染、小量數(shù)據(jù)更新、大量數(shù)據(jù)更新這些不同的場合。Virtual DOM、臟檢查 MVVM、數(shù)據(jù)收集 MVVM 在不同場合各有不同的表現(xiàn)和不同的優(yōu)化需求。Virtual DOM 為了提升小量數(shù)據(jù)更新時的性能,也需要針對性的優(yōu)化,比如 shouldComponentUpdate 或是 immutable data。
初始渲染:Virtual DOM > 臟檢查 >= 依賴收集
小量數(shù)據(jù)更新:依賴收集 >> Virtual DOM + 優(yōu)化 > 臟檢查(無法優(yōu)化) > Virtual DOM 無優(yōu)化
大量數(shù)據(jù)更新:臟檢查 + 優(yōu)化 >= 依賴收集 + 優(yōu)化 > Virtual DOM(無法/無需優(yōu)化)>> MVVM 無優(yōu)化
(該段落借鑒了知乎的相關(guān)回答)
四、對React虛擬DOM的誤解?
React 從來沒有說過 “React 比原生操作 DOM 快”。React給我們的保證是,在不需要手動優(yōu)化的情況下,它依然可以給我們提供過得去的性能。
React掩蓋了底層的 DOM 操作,可以用更聲明式的方式來描述我們目的,從而讓代碼更容易維護(hù)。下面還是借鑒了知乎上的回答:沒有任何框架可以比純手動的優(yōu)化 DOM 操作更快,因?yàn)榭蚣艿?DOM 操作層需要應(yīng)對任何上層 API 可能產(chǎn)生的操作,它的實(shí)現(xiàn)必須是普適的。針對任何一個 benchmark,我都可以寫出比任何框架更快的手動優(yōu)化,但是那有什么意義呢?在構(gòu)建一個實(shí)際應(yīng)用的時候,你難道為每一個地方都去做手動優(yōu)化嗎?出于可維護(hù)性的考慮,這顯然不可能。
相信看了本文案例你已經(jīng)掌握了方法,更多精彩請關(guān)注php中文網(wǎng)其它相關(guān)文章!
推薦閱讀:
微信小程序內(nèi)實(shí)現(xiàn)上傳圖片附后端代碼
Atas ialah kandungan terperinci 怎樣使用React虛擬DOM. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Alat AI Hot

Undress AI Tool
Gambar buka pakaian secara percuma

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Clothoff.io
Penyingkiran pakaian AI

Video Face Swap
Tukar muka dalam mana-mana video dengan mudah menggunakan alat tukar muka AI percuma kami!

Artikel Panas

Alat panas

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6
Alat pembangunan web visual

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Vue.js dan bertindak balas masing -masing mempunyai kelebihan mereka sendiri: vue.js sesuai untuk aplikasi kecil dan perkembangan pesat, sementara React sesuai untuk aplikasi besar dan pengurusan negara yang kompleks. 1.vue.js Menyedari kemas kini automatik melalui sistem responsif, sesuai untuk aplikasi kecil. 2. REACT menggunakan algoritma DOM dan Diff Virtual, yang sesuai untuk aplikasi besar dan kompleks. Apabila memilih rangka kerja, anda perlu mempertimbangkan keperluan projek dan timbunan teknologi pasukan.

Netflix memilih React untuk membina antara muka penggunanya kerana reka bentuk komponen React dan mekanisme DOM maya dapat mengendalikan antara muka yang kompleks dan kemas kini yang kerap. 1) Reka bentuk berasaskan komponen membolehkan Netflix memecah antara muka ke dalam widget yang boleh diurus, meningkatkan kecekapan pembangunan dan pemeliharaan kod. 2) Mekanisme DOM maya memastikan kelancaran dan prestasi tinggi antara muka pengguna Netflix dengan meminimumkan operasi DOM.

10 platform aplikasi perdagangan mata wang digital teratas: 1. Okx, 2. Binance, 3. Gate.io, 4. Huobi, 5. Coinbase, 6. Kraken, 7.

Terdapat lima cara untuk memasukkan CSS dalam React: 1. Gunakan gaya inline, yang mudah tetapi tidak kondusif untuk digunakan semula dan penyelenggaraan; 2. Gunakan fail CSS, yang dilaksanakan melalui import, yang kondusif kepada organisasi tetapi boleh menyebabkan konflik; 3. Gunakan cssmodul untuk mengelakkan konflik global tetapi memerlukan konfigurasi; 4. Gunakan styledcomponents untuk menghasilkan gaya secara dinamik menggunakan JavaScript tetapi memerlukan pergantungan pada perpustakaan; 5. Gunakan sass atau kurang untuk menyediakan lebih banyak fungsi tetapi meningkatkan kerumitan pembinaan.

Trend masa depan dan ramalan Vue.js dan React adalah: 1) Vue.js akan digunakan secara meluas dalam aplikasi peringkat perusahaan dan telah membuat terobosan dalam penjanaan tapak dan penjanaan tapak statik; 2) React akan berinovasi dalam komponen pelayan dan pemerolehan data, dan terus mengoptimumkan model keserasian.

Vue.js sesuai untuk projek kecil dan sederhana, manakala React sesuai untuk projek besar dan senario aplikasi yang kompleks. 1) Vue.js mudah digunakan dan sesuai untuk prototaip cepat dan aplikasi kecil. 2) React mempunyai lebih banyak kelebihan dalam mengendalikan pengurusan negara yang kompleks dan pengoptimuman prestasi, dan sesuai untuk projek besar.

React dan Bootstrap boleh diintegrasikan dengan lancar untuk meningkatkan reka bentuk antara muka pengguna. 1) Pasang Pakej Ketergantungan: NPMinstallBootstrapReact-Bootstrap. 2) Import fail CSS: import'bootstrap/dist/css/bootstrap.min.css '. 3) Gunakan komponen bootstrap seperti butang dan bar navigasi. Dengan gabungan ini, pemaju boleh memanfaatkan fleksibiliti React dan perpustakaan gaya Bootstrap untuk mewujudkan antara muka pengguna yang indah dan cekap.

Ya, reactapplicationscanbeseo-friendlywithpropstrategies.1) useserver-siderendering (ssr) withtoolslikenext.jstogeneratenerlhtmlforindexing.2) pelaksanaan stationsitationeration (ssg) forcontent-heavysitestopre-renderpageStoStoStoStoStoStoStoStoStoStoStoStoStoStoStoStoStoStoStoStoStoStoStetBuild
