iT邦幫忙

2022 iThome 鐵人賽

DAY 4
2

就如同官方文件所描述的,React 是一個用於「打造 UI」的工具,而在瀏覽器中我們呈現 UI 的載體就是 DOM。DOM 與瀏覽器的畫面渲染引擎綁定,因此操作 DOM 就會連動更新畫面繪製的結果。而在像是 React 這種現代的前端解決方案中,我們一般來說並不會直接自己去操作 DOM,而是透過 React 所建立的抽象層幫我們代為進行 DOM 的管理,大多數時候我們只需要負責跟 React 提供的 API 互動就好。

因此,想要真正的從基礎好好理解 React 的運作方式,就必須從 DOM 以及 React 的代理抽象層之間的關係開始著手剖析。


DOM

在開始進入 React 之前,我們先稍微複習一下關於瀏覽器中的 DOM。

DOM(Document Object Model)是存在於瀏覽器 JavaScript 環境中的樹狀資料結構,用來描述瀏覽器畫面中的節點,每個節點實際上是一個 JS 物件,這個物件除了包含了該元素的一些屬性,還提供了一些介面(方法),以便調用於插入和操作 DOM。

DOM 節點與瀏覽器中的渲染引擎綁定,當我們在操作 DOM 的時候就會連帶觸發瀏覽器的渲染引擎進行一連串更新畫面的流程,因此 DOM 的操作在效能上是相對昂貴的動作,當畫面上有大量的 DOM 在短時間內異動時更容易出現畫面上的卡頓等等問題。因此,在瀏覽器中盡可能地減少 DOM 操作 —— 具體來說,應該是「以最少的 DOM 操作來達到所需要的畫面結果」,將會是前端效能優化的重要關鍵。


Virtual DOM

我們先不著急著進入到 React 本身的部分。在那之前,我們得先引入一個 React 核心機制背後所採用的重要概念:Virtual DOM。

如前文所述,DOM 的操作由於會直接連動到瀏覽器渲染引擎的一系列行為,因此是非常花費效能的動作。因此為了改善操作「真實」DOM 所帶來的效能問題,衍生出了「Virtual DOM」的概念。意義上來說,Virtual DOM 是真實 DOM 的虛構描述體,它實際上也是一種樹狀結構的資料。

每一個 Virtual DOM element 的資料都是普通的 JavaScript 物件變數,內容則嘗試在描述一個真實的 DOM element 預計要長的樣子(像是元素類型、屬性、子元素有哪些…等等資訊)。接著透過負責渲染畫面的程式處理後,就能將 Virtual DOM element 轉換並產生成實際的 DOM element,以更新瀏覽器的實際畫面。

有一種在學習 React 時常見的誤解是認為「Virtual DOM 是從真實 DOM 複製一份出來的 copy」,不過事實上正好相反:

實際上是先自行以 Virtual DOM 來定義預計想要的畫面結構,然後再將這個結構的描述轉換成真實的 DOM Tree(也就是去操作真實 DOM Tree 來同步為長得跟 Virtual DOM 對應一致)。因此,這兩者之間的同步關係應該是由 Virtual DOM => DOM 單向的才對。開發者對 Virtual DOM 進行管理與互動,而由 Virtual DOM 到真實 DOM 的同步則由程式自動處理。

然而,多了這麼一層處理的好處是什麼呢?

你可以想像 Virtual DOM 就像是畫面產生的模擬彩排場,每次有新 UI 畫面產生的需求時,我們可以用以下流程來完成畫面更新:

  1. 透過事先定義好的模板程式來產生新的 Virtual DOM Tree ,作為新的彩排結果
  2. 並且與此前最後一次舊畫面用的 Virtual DOM Tree 進行兩棵樹的結構細節比較,其中差異之處才是本次畫面更新中真正有需要變更的部分
  3. 將新舊 Virtual DOM Tree 中有差異的部分更新到真實的 DOM Tree 中,以完成瀏覽器畫面的更新

透過這個流程,我們就可以將真實的 DOM 操作範圍最小化,並限縮在這些真正需要變更的地方,來盡可能的減少因 DOM 操作而造成的效能花費。


圖片來源:https://medium.com/手寫筆記/build-a-simple-virtual-dom-5cf12ccf379f

雖然每次重新產生畫面的 Virtual DOM 資料,並且與舊有的 Virtual DOM 進行詳細的樹狀結構比較都會有效能上的花費,但是畢竟操作的是普通的 JavaScript 物件資料,並且與真實的 DOM 不同的是,Virtual DOM 並沒有與瀏覽器的渲染引擎做直接的綁定,因此整體來說還是比頻繁且大量的操作真實 DOM 的效能花費要低了許多。

一些主流前端的框架或解決方案就採用了這種概念來實作並管理畫面的抽象層,當然其中包含了我們的系列文主角 React。不同框架或解決方案對於 Virtual DOM 概念的實踐以及比較的方式可能不盡相同,不過觀念上都是以這種虛擬的抽象層來代理 DOM 的處理。畢竟這是有關於 React 的系列文,因此以上的描述是比較基於 React 所採納的概念來介紹。

如果你覺得以上的概念描述有點抽象、難以想像實際上在撰寫的程式中是如何運行的話,也不用感到緊張覺得開始跟不上了,此處的簡介只是為了先讓我們對於 Virtual DOM 的概念與設計緣由有個基本的認識作為鋪陳。而在後續的篇幅中,我們還會再更進一步的介紹 Virtual DOM 的概念在 React 的畫面更新流程中所扮演的角色,並對應到實際的程式碼流程來做細節的解析,相信到時候大家就能夠對於其觀念能有更深的體察與感受。

推薦進階參考資源:關於 Virtual DOM 效益的進階討論

在介紹完了背景的緣由以及大致觀念之後,下一篇就讓我們進入到 Virtual DOM 概念在 React 中的實現的最小組成單位:React element。


2024/2 更新 - 實體書平裝版本預購

在經過快要一年的努力後,本系列文的實體書版本推出了~其中新增並補充了許多鐵人賽版本中沒有的脈絡與細節,並以全彩印刷拉滿視覺上的閱讀體驗,現正熱銷中!有興趣的話歡迎參考看看,也歡迎分享給其他有接觸前端的朋友們,非常感謝大家~

《React 思維進化:一次打破常見的觀念誤解,躍升專業前端開發者》

目前首刷的軟精裝版本各大通路已經幾乎都銷售一空,接下來會再刷推出新的平裝版本:

天瓏(平裝版預購):
https://www.tenlong.com.tw/products/9786263337695

博客來(平裝版):
https://www.books.com.tw/products/0010982322

momo(平裝版):
https://www.momoshop.com.tw/goods/GoodsDetail.jsp?i_code=12528845


上一篇
[Day 03] React 開發環境建置的門檻
下一篇
[Day 05] 建構一切 UI 的最基本單位 — React element
系列文
一次打破 React 常見的學習門檻與觀念誤解30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言