如果您正在使用React或學習React,那么您一定聽說過“虛擬DOM”一詞。現在什么是虛擬DOM?為什么React使用它?
真實DOM
首先,DOM代表“文檔對象模型”。DOM用簡單的語言表示應用程序的UI。每當應用程序UI的狀態發生變化時,DOM都會更新以表示該變化。現在,問題是經常操縱DOM影響性能,使其變慢。
是什么導致DOM操作緩慢?
DOM表示為樹數據結構。因此,DOM的更改和更新很快。但是在更改之后,必須重新渲染已更新的元素及其子元素以更新應用程序UI。UI的重新渲染或重新繪制使它變慢。因此,您擁有的UI組件越多,DOM更新的成本就越高,因為每次DOM更新都需要重新渲染它們。
虛擬DOM
那就是虛擬DOM概念出現的地方,并且其性能要比真實DOM好得多。虛擬DOM只是DOM的虛擬表示。每當我們的應用程序狀態更改時,虛擬DOM就會更新,而不是真實DOM。
好吧,您可能會問:“虛擬DOM是否與真實DOM所做的相同,這聽起來像是雙重工作?這比僅僅更新真實的DOM還要快嗎?”
答案是虛擬DOM更快,更高效,這就是原因。
虛擬DOM如何更快?
將新元素添加到UI時,將創建表示為樹的虛擬DOM。每個元素都是該樹上的一個節點。如果這些元素中任何一個的狀態改變,那么將創建一個新的虛擬DOM樹。然后將該樹與先前的虛擬DOM樹進行比較或“差異化”。
完成此操作后,虛擬DOM將計算出最佳方法以對真實DOM進行這些更改。這樣可以確保對實際DOM的操作最少。因此,降低了更新實際DOM的性能成本。
下圖顯示了虛擬DOM樹和差異化過程。
紅色圓圈表示已更改的節點。這些節點表示狀態已更改的UI元素。然后計算虛擬DOM樹的先前版本與當前虛擬DOM樹之間的差異。然后重新渲染整個父子樹以提供更新的UI。然后將此更新的樹批量更新為真實的DOM。
React如何使用虛擬DOM
現在您對虛擬DOM是什么以及它如何對您的應用程序性能有所了解了,讓我們了解一下React如何利用虛擬DOM。
在React中,每個UI塊都是一個組件,每個組件都有一個狀態。React遵循可觀察的模式,并監聽狀態變化。當組件的狀態改變時,React更新虛擬DOM樹。虛擬DOM更新后,React然后將虛擬DOM的當前版本與虛擬DOM的先前版本進行比較。此過程稱為“差異化”。
一旦React知道哪些虛擬DOM對象已更改,然后React就會在真實DOM中僅 更新那些對象。與直接操作真實DOM相比,這使性能好得多。這使React作為高性能JavaScript庫脫穎而出。
簡而言之,您可以告訴React您希望UI處于什么狀態,并確保DOM匹配該狀態。這里最大的好處是,作為開發人員,您將不需要知道如何在后臺進行屬性操縱,事件處理或手動DOM更新。
所有這些細節都是從React開發人員那里抽象出來的。您需要做的就是在需要時更新組件的狀態,React負責其余的工作。這樣可以確保在使用React時獲得卓越的開發人員體驗。
React render()
函數
render()
是更新和渲染UI的位置。render()
是React中必需的生命周期方法。render()
函數是創建React元素樹的入口點。當組件中的狀態或道具更新時,render()
將返回不同的React元素樹。如果在組件內使用setState()
,React會立即檢測到狀態更改并重新渲染組件。
然后,React找出如何有效地更新UI以匹配最新的樹更改。
這是當React首先更新其虛擬DOM并僅更新實際DOM中已更改的對象時。
批量更新
React遵循批處理更新機制來更新實際DOM。因此,導致性能提高。這意味著對真實DOM的更新將分批發送,而不是針對狀態的每個單個更改發送更新。
UI的重新繪制是最昂貴的部分,React有效地確保了真正的DOM僅接收批量更新來重新繪制UI
總結
- 頻繁的DOM操作昂貴且性能沉重。
- 虛擬DOM是真實DOM的虛擬表示。
- 狀態發生變化時,將更新虛擬DOM,并比較虛擬DOM的先前版本和當前版本。這稱為
diff
。 - 然后,虛擬DOM將批量更新發送到真實DOM以更新UI。
- React使用虛擬DOM來增強其性能。
- 它使用可觀察對象來檢測狀態和道具更改。
- React使用高效的差異算法來比較虛擬DOM的版本。
- 然后,確保將批處理的更新發送到真實的DOM,以重新繪制或重新呈現UI。