



下載本文檔
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
【移動應(yīng)用開發(fā)技術(shù)】如何使用React虛擬DOM
在下給大家分享一下如何使用React虛擬DOM,希望大家閱讀完這篇文章后大所收獲,下面讓我們一起去探討吧!在Web開發(fā)中,需要將數(shù)據(jù)的變化實(shí)時(shí)反映到UI上,這時(shí)就需要對DOM進(jìn)行操作,但是復(fù)雜或頻繁的DOM操作通常是性能瓶頸產(chǎn)生的原因,為此,React引入了虛擬DOM(VirtualDOM)的機(jī)制。一、什么是虛擬DOM?在React中,render執(zhí)行的結(jié)果得到的并不是真正的DOM節(jié)點(diǎn),結(jié)果僅僅是輕量級的JavaScript對象,我們稱之為virtualDOM。虛擬DOM是React的一大亮點(diǎn),具有batching(批處理)和高效的Diff算法。這讓我們可以無需擔(dān)心性能問題而”毫無顧忌”的隨時(shí)“刷新”整個頁面,由虛擬DOM來確保只對界面上真正變化的部分進(jìn)行實(shí)際的DOM操作。在實(shí)際開發(fā)中基本無需關(guān)心虛擬DOM是如何運(yùn)作的,但是理解其運(yùn)行機(jī)制不僅有助于更好的理解React組件的生命周期,而且對于進(jìn)一步優(yōu)化React程序也會有很大幫助。二、虛擬DOMVS直接操作原生DOM?如果沒有VirtualDOM,簡單來說就是直接重置innerHTML。這樣操作,在一個大型列表所有數(shù)據(jù)都變了的情況下,還算是合理,但是,當(dāng)只有一行數(shù)據(jù)發(fā)生變化時(shí),它也需要重置整個innerHTML,這時(shí)候顯然就造成了大量浪費(fèi)。比較innerHTML和VirtualDOM的重繪過程如下:innerHTML:renderhtmlstring+重新創(chuàng)建所有DOM元素VirtualDOM:renderVirtualDOM+diff+必要的DOM更新和DOM操作比起來,js計(jì)算是非常便宜的。VirtualDOMrender+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)頁面需要更新時(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;
if(!(i
%
50))
{
container.innerHTML
=
html;
}
}
...
}這樣來看,React的性能就遠(yuǎn)勝于原生DOM操作了。而且,DOM完全不屬于Javascript(也不在Javascript引擎中存在).。Javascript其實(shí)是一個非常獨(dú)立的引擎,DOM其實(shí)是瀏覽器引出的一組讓Javascript操作HTML文檔的API而已。在即時(shí)編譯的時(shí)代,調(diào)用DOM的開銷是很大的。而VirtualDOM的執(zhí)行完全都在Javascript引擎中,完全不會有這個開銷。React.js相對于直接操作原生DOM有很大的性能優(yōu)勢,很大程度上都要?dú)w功于virtualDOM的batching和diff。batching把所有的DOM操作搜集起來,一次性提交給真實(shí)的DOM。diff算法時(shí)間復(fù)雜度也從標(biāo)準(zhǔn)的的Diff算法的O(n^3)降到了O(n)。這里留到下一次博客單獨(dú)講。三、虛擬DOMVSMVVM?相比起React,其他MVVM系框架比如Angular,Knockout以及Vue、Avalon采用的都是數(shù)據(jù)綁定:通過Directive/Binding對象,觀察數(shù)據(jù)變化并保留對實(shí)際DOM元素的引用,當(dāng)有數(shù)據(jù)變化時(shí)進(jìn)行對應(yīng)的操作。MVVM的變化檢查是數(shù)據(jù)層面的,而React的檢查是DOM結(jié)構(gòu)層面的。MVVM的性能也根據(jù)變動檢測的實(shí)現(xiàn)原理有所不同:Angular的臟檢查使得任何變動都有固定的O(watchercount)的代價(jià);Knockout/Vue/Avalon都采用了依賴收集,在js和DOM層面都是O(change):臟檢查:scopedigest+必要DOM更新依賴收集:重新收集依賴+必要DOM更新可以看到,Angular最不效率的地方在于任何小變動都有的和watcher數(shù)量相關(guān)的性能代價(jià)。但是!當(dāng)所有數(shù)據(jù)都變了的時(shí)候,Angular其實(shí)并不吃虧。依賴收集在初始化和數(shù)據(jù)變化的時(shí)候都需要重新收集依賴,這個代價(jià)在小量更新的時(shí)候幾乎可以忽略,但在數(shù)據(jù)量龐大的時(shí)候也會產(chǎn)生一定的消耗。MVVM渲染列表的時(shí)候,由于每一行都有自己的數(shù)據(jù)作用域,所以通常都是每一行有一個對應(yīng)的ViewModel實(shí)例,或者是一個稍微輕量一些的利用原型繼承的"scope"對象,但也有一定的代價(jià)。所以,MVVM列表渲染的初始化幾乎一定比React慢,因?yàn)閯?chuàng)建ViewModel/scope實(shí)例比起VirtualDOM來說要昂貴很多。這里所有MVVM實(shí)現(xiàn)的一個共同問題就是在列表渲染的數(shù)據(jù)源變動時(shí),尤其是當(dāng)數(shù)據(jù)是全新的對象時(shí),如何有效地復(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。這時(shí)候你就可以提示trackbyuid來讓Angular知道,這兩個對象其實(shí)是同一份數(shù)據(jù)。那么原來這份數(shù)據(jù)對應(yīng)的實(shí)例和DOM元素都可以復(fù)用,只需要更新變動了的部分?;蛘?,你也可以直接trackby$index來進(jìn)行“原地復(fù)用”:直接根據(jù)在數(shù)組里的位置進(jìn)行復(fù)用。在題目給出的例子里,如果angular實(shí)現(xiàn)加上trackby$index的話,后續(xù)重繪是不會比React慢多少的。甚至在dbmonster測試中,Angular和Vue用了trackby$index以后都比React快:dbmon(注意Angular默認(rèn)版本無優(yōu)化,優(yōu)化過的在下面)在比較性能的時(shí)候,要分清楚初始渲染、小量數(shù)據(jù)更新、大量數(shù)據(jù)更新這些不同的場合。VirtualDOM、臟檢查MVVM、數(shù)據(jù)收集MVVM在不同場合各有不同的表現(xiàn)和不同的優(yōu)化需求。VirtualDOM為了提升小量數(shù)據(jù)更新時(shí)的性能,也需要針對性的優(yōu)化,比如shouldComponentUpdate或是immutabledata。初始渲染:VirtualDOM>臟檢查>=依賴收集小量數(shù)據(jù)更新:依賴收集>>VirtualDOM+優(yōu)化>臟檢查(無法優(yōu)化)>VirtualDOM無優(yōu)化大量數(shù)據(jù)更新:臟檢查+優(yōu)化>=依賴收集+優(yōu)化>VirtualDOM(無法/無需優(yōu)化)>>MVVM無優(yōu)化(該段落借鑒了知乎的相關(guān)回答)四、對React虛擬DOM的誤解?React從來沒有說過“React比原生操作DOM快”。React給我們的保證是,在不需要手動優(yōu)化的情況下,它依然可以給我們提供過得去的性能。React掩蓋了底層的DOM操作,可以用更聲明式
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 6.3二氧化碳的實(shí)驗(yàn)室制?。ǖ诙n時(shí))-人教版九年級《化學(xué)》上冊教學(xué)課件
- 智能預(yù)約系統(tǒng)優(yōu)化景區(qū)游客容量管理-洞察闡釋
- 圖論在量子計(jì)算中的潛力-洞察闡釋
- 高中音樂跨學(xué)科教學(xué)中的評估與反思策略
- 高中科技創(chuàng)新跨學(xué)科教學(xué)在提升學(xué)生綜合能力中的作用
- 2025至2030年中國洗模劑行業(yè)投資前景及策略咨詢報(bào)告
- 高中思想政治教師跨學(xué)科素養(yǎng)與專業(yè)發(fā)展路徑
- 初三數(shù)學(xué)專題復(fù)習(xí)教學(xué)設(shè)計(jì)和教學(xué)
- 《資源跨區(qū)域調(diào)配》教學(xué)設(shè)計(jì)(第一課時(shí))
- 四川省瀘州市2022-2023學(xué)年高二下學(xué)期期末數(shù)學(xué)(文科)試題(教師版)
- 安徽省阜陽市太和縣2023-2024學(xué)年八年級下學(xué)期期末英語試題
- 個體診所備案承諾書模板
- 危險(xiǎn)化學(xué)品倉庫安全檢查表
- 2024年咨詢工程師繼續(xù)教育城市軌道交通工程可行性研究報(bào)告編制方法考試答案
- 版隧道檢驗(yàn)批施工質(zhì)量驗(yàn)收表格
- 倉儲管理職位工作手冊完整版
- 2024年云南省曲靖經(jīng)開區(qū)政法委招聘2人歷年高頻考題難、易錯點(diǎn)模擬試題(共500題)附帶答案詳解
- 2024中國成人健康管理洞察之益生菌部分-益普索-202405
- 2024年云南昆明市石林彝族自治縣公安局勤務(wù)輔警招聘筆試參考題庫附帶答案詳解
- 產(chǎn)科危重癥病人的護(hù)理
- 2024年山東省濟(jì)南市市中區(qū)中考二模地理試卷
評論
0/150
提交評論