如果您正在使用React或?qū)W習(xí)React锌杀,那么您一定聽說過“虛擬DOM”一詞∈チ裕現(xiàn)在什么是虛擬DOM?為什么React使用它隘弊?
真實(shí)DOM
首先哈踱,DOM代表“文檔對(duì)象模型”。DOM用簡(jiǎn)單的語(yǔ)言表示應(yīng)用程序的UI梨熙。每當(dāng)應(yīng)用程序UI的狀態(tài)發(fā)生變化時(shí)开镣,DOM都會(huì)更新以表示該變化。現(xiàn)在咽扇,問題是經(jīng)常操縱DOM影響性能邪财,使其變慢。
是什么導(dǎo)致DOM操作緩慢质欲?
DOM表示為樹數(shù)據(jù)結(jié)構(gòu)树埠。因此,DOM的更改和更新很快嘶伟。但是在更改之后怎憋,必須重新渲染已更新的元素及其子元素以更新應(yīng)用程序UI。UI的重新渲染或重新繪制使它變慢九昧。因此盛霎,您擁有的UI組件越多,DOM更新的成本就越高耽装,因?yàn)槊看蜠OM更新都需要重新渲染它們愤炸。
虛擬DOM
那就是虛擬DOM概念出現(xiàn)的地方,并且其性能要比真實(shí)DOM好得多掉奄。虛擬DOM只是DOM的虛擬表示规个。每當(dāng)我們的應(yīng)用程序狀態(tài)更改時(shí)凤薛,虛擬DOM就會(huì)更新,而不是真實(shí)DOM诞仓。
好吧缤苫,您可能會(huì)問:“虛擬DOM是否與真實(shí)DOM所做的相同,這聽起來(lái)像是雙重工作墅拭?這比僅僅更新真實(shí)的DOM還要快嗎活玲?”
答案是虛擬DOM更快,更高效谍婉,這就是原因舒憾。
虛擬DOM如何更快?
將新元素添加到UI時(shí)穗熬,將創(chuàng)建表示為樹的虛擬DOM镀迂。每個(gè)元素都是該樹上的一個(gè)節(jié)點(diǎn)。如果這些元素中任何一個(gè)的狀態(tài)改變唤蔗,那么將創(chuàng)建一個(gè)新的虛擬DOM樹探遵。然后將該樹與先前的虛擬DOM樹進(jìn)行比較或“差異化”。
完成此操作后妓柜,虛擬DOM將計(jì)算出最佳方法以對(duì)真實(shí)DOM進(jìn)行這些更改箱季。這樣可以確保對(duì)實(shí)際DOM的操作最少。因此棍掐,降低了更新實(shí)際DOM的性能成本规哪。
下圖顯示了虛擬DOM樹和差異化過程。
紅色圓圈表示已更改的節(jié)點(diǎn)塌衰。這些節(jié)點(diǎn)表示狀態(tài)已更改的UI元素。然后計(jì)算虛擬DOM樹的先前版本與當(dāng)前虛擬DOM樹之間的差異蝠嘉。然后重新渲染整個(gè)父子樹以提供更新的UI最疆。然后將此更新的樹批量更新為真實(shí)的DOM。
React如何使用虛擬DOM
現(xiàn)在您對(duì)虛擬DOM是什么以及它如何對(duì)您的應(yīng)用程序性能有所了解了蚤告,讓我們了解一下React如何利用虛擬DOM努酸。
在React中,每個(gè)UI塊都是一個(gè)組件杜恰,每個(gè)組件都有一個(gè)狀態(tài)获诈。React遵循可觀察的模式,并監(jiān)聽狀態(tài)變化心褐。當(dāng)組件的狀態(tài)改變時(shí)舔涎,React更新虛擬DOM樹。虛擬DOM更新后逗爹,React然后將虛擬DOM的當(dāng)前版本與虛擬DOM的先前版本進(jìn)行比較亡嫌。此過程稱為“差異化”。
一旦React知道哪些虛擬DOM對(duì)象已更改,然后React就會(huì)在真實(shí)DOM中僅 更新那些對(duì)象挟冠。與直接操作真實(shí)DOM相比于购,這使性能好得多。這使React作為高性能JavaScript庫(kù)脫穎而出知染。
簡(jiǎn)而言之肋僧,您可以告訴React您希望UI處于什么狀態(tài),并確保DOM匹配該狀態(tài)控淡。這里最大的好處是嫌吠,作為開發(fā)人員,您將不需要知道如何在后臺(tái)進(jìn)行屬性操縱逸寓,事件處理或手動(dòng)DOM更新居兆。
所有這些細(xì)節(jié)都是從React開發(fā)人員那里抽象出來(lái)的。您需要做的就是在需要時(shí)更新組件的狀態(tài)竹伸,React負(fù)責(zé)其余的工作泥栖。這樣可以確保在使用React時(shí)獲得卓越的開發(fā)人員體驗(yàn)。
React render()
函數(shù)
render()
是更新和渲染UI的位置勋篓。render()
是React中必需的生命周期方法吧享。render()
函數(shù)是創(chuàng)建React元素樹的入口點(diǎn)。當(dāng)組件中的狀態(tài)或道具更新時(shí)譬嚣,render()
將返回不同的React元素樹钢颂。如果在組件內(nèi)使用setState()
,React會(huì)立即檢測(cè)到狀態(tài)更改并重新渲染組件拜银。
然后殊鞭,React找出如何有效地更新UI以匹配最新的樹更改。
這是當(dāng)React首先更新其虛擬DOM并僅更新實(shí)際DOM中已更改的對(duì)象時(shí)尼桶。
批量更新
React遵循批處理更新機(jī)制來(lái)更新實(shí)際DOM操灿。因此,導(dǎo)致性能提高泵督。這意味著對(duì)真實(shí)DOM的更新將分批發(fā)送趾盐,而不是針對(duì)狀態(tài)的每個(gè)單個(gè)更改發(fā)送更新。
UI的重新繪制是最昂貴的部分小腊,React有效地確保了真正的DOM僅接收批量更新來(lái)重新繪制UI
總結(jié)
- 頻繁的DOM操作昂貴且性能沉重救鲤。
- 虛擬DOM是真實(shí)DOM的虛擬表示。
- 狀態(tài)發(fā)生變化時(shí)秩冈,將更新虛擬DOM本缠,并比較虛擬DOM的先前版本和當(dāng)前版本。這稱為
diff
入问。 - 然后搓茬,虛擬DOM將批量更新發(fā)送到真實(shí)DOM以更新UI犹赖。
- React使用虛擬DOM來(lái)增強(qiáng)其性能。
- 它使用可觀察對(duì)象來(lái)檢測(cè)狀態(tài)和道具更改卷仑。
- React使用高效的差異算法來(lái)比較虛擬DOM的版本峻村。
- 然后,確保將批處理的更新發(fā)送到真實(shí)的DOM锡凝,以重新繪制或重新呈現(xiàn)UI粘昨。