虛擬DOM比你想象的更強大

2024年2月6日 18点热度 0人点赞

如果你對網站開發領域感興趣,你可能聽說過虛擬DOM - 它是JavaScript創建的一個對真實DOM的表示,像React這樣的庫使用它來跟蹤響應性。

然而,近年來,許多庫和框架對於虛擬DOM的有效性提出了質疑,而類似Svelte和Solid的項目表明,細粒度的響應性比DOM的抽象更快速和易於使用。

"This unlocks complete control over what gets updated and when, even at the DOM binding level. With no Virtual DOM or extensive diffing, the framework never does more work than you want it to."

這將完全解鎖對更新內容以及更新時間的完全控制,即使是在DOM綁定層面。沒有虛擬DOM或廣泛的差異比較,該框架永遠不會超出您所希望的工作范圍。

-SolidJS

那麼為什麼像 Meta(React)和Google(Angular) 這樣的卓越工程師會遵循這個模式呢?僅僅是因為細粒度的響應性不可能嗎?

並非如此。事實證明,虛擬DOM的能力遠超出許多人所意識到的 - 實際上,它的功能和可用性甚至遠遠超出了它最初為之創造的平臺,即互聯網。

開始

一切始於2013年,當虛擬DOM的模式與React一起發佈時。虛擬DOM背後的想法很簡單-以批次更新。

在那個時候,通過JavaScript操作DOM非常痛苦。像jQuery這樣的庫已經在改善這個問題上取得了進展,但是快速操作DOM仍然可能會對性能造成影響。

批處理響應性

React團隊提出了一種不同的方法。不是為了實現響應性而更新每個值和元素,而是將改變一起批處理,然後同時推送到DOM中。

於是,虛擬DOM誕生了。通過在JavaScript中表示DOM,可以快速進行更改和計算,然後再推送到實際的DOM。

卓越的救命稻草還是性能拖累表現?

在過去的幾年中,React已經成為開發響應式Web應用程序的主要選擇,並且至今仍然如此。很容易理解為什麼 - 標記語言被視為函數,ui = f(state)的想法既簡單又強大。

話雖如此,很明顯虛擬DOM並非一帆風順。隻需看看最近一個關於React性能問題的例子——useMemo()鉤子和React Forget,就能明白。

useMemo()鉤子

在2019年,React發佈了useMemo() hook,旨在解決React性能方面的一個重大問題。由於React追蹤響應性,你常常會遇到由於元素被不必要地更新而導致性能瓶頸的情況。

為了解決這個問題,React團隊向該庫引入了記憶化技術。記憶化是一種存儲或緩存由耗時函數生成的值的技術。通過引入useMemo()鉤子函數,React開發人員可以告訴框架在何時不更新元素,極大地提高了性能。

但是引入useMemo()進一步復雜化了本應簡化網頁開發的內容,並且打斷了React先前的邏輯流程。

React Forget

直到今天,React仍在努力解決這個問題。最近,React在庫中為新的編譯器React Forgot取得了進展,該編譯器利用分析來在構建時自動進行記憶化。

但是盡管React Forget極大地簡化了開發者的體驗,它仍然需要進行大量的工作來解決一個簡單的問題,因為編譯器必須分析您的代碼並智能地識別應該在哪裡添加useMemo()。

ℹ️ React Forget 還在開發中,但我們已經在像 Meta Quest Store 和 Instagram 這樣的生產應用中看到了它的蹤跡,所以很快就會有更多的消息

像Svelte和Solid這樣的其他框架不必處理這個問題,因為它們能夠隻更新需要更改的部分。這大大提升了開發體驗(DX),用戶體驗(UX)和構建時間。

一個隱藏的力量

所以,你可能會認為,虛擬 DOM 沒有任何意義。它速度慢,使得開發體驗更糟糕,並且甚至沒有比傳統細粒度響應性更好的優勢。

但是盡管這些觀點中有很多是正確的,而虛擬 DOM 有一點拯救之恩,那就是它使得 React 非常強大 - 虛擬 DOM 不僅限於網頁。

超越網頁

如果你曾經創建過一個React項目,你就會知道至少需要兩個依賴 - react和react-dom。當我第一次接觸React時,我覺得這很奇怪,但原因是因為react包生成了虛擬DOM,而react-dom包實際上將其渲染到真實的DOM中。

這是什麼意思?本質上,任何人都可以創建能夠解釋React虛擬DOM並生成各種輸出的包。通過react-dom渲染到Web隻是一種方法而已。

庫和框架

我們已經看到這在許多令人難以置信的庫和框架中得到了應用。React Native利用虛擬DOM創建了適用於iOS和Android的本地組件。Remotion利用虛擬DOM創建了真實的.mp4視頻。React Three Fiber使您能夠隻使用React渲染完整的3D場景。

確實沒有限制。 這裡甚至有一個由令人難以置信的Poimandres團隊開發的項目叫做react-nil,它不會渲染任何內容-相反,它隻是通過React抽象讓你構建服務器和命令行接口。

這項策略的影響是巨大的,因為它意味著React作為一個共同的接口可以通過計算機完成幾乎任何事情。React的組件和狀態思維非常有用,而虛擬DOM則使得這種思維無處不在。

警告

當然,伴隨著強大的力量而來的是後果。很多時候,React並不是做某事的最佳方式,因此重要的是要仔細考慮是否將React作為您所做的任何事情的界面是否真正是正確的方式。

結論

總之,虛擬DOM真的很強大,因為它簡單地將組件接口轉換為對象,並且可以輕松地以任何方式進行操作和解釋。

在這篇文章中,我們主要通過React的角度來看待它,但是其他工具如Angular和Vue也使用類似的策略,盡管有所不同。

你認為虛擬DOM是一個革命性的變革,還是一個不必要的抽象?React是否真正是一個通用的接口,還是應當局限於網絡?最後,你對於利用虛擬DOM來創造其他東西有什麼想法?無限的可能性確實存在。