## React 思維進化讀書會 --- Evan - 非本科轉職(食品科學系畢業) - Alpha camp - 前端工程師 - 一年 Angular 開發經驗 --- #### 2-1 DOM 與 Virtual DOM #### 2-2 建構畫面的最小單位:React element #### 2-3 Render React element --- 2-1 DOM 與 Virtual DOM --- ### DOM 是什麼? - 一種樹狀結構資料,用來表示畫面中的結構元素 - 一個元素就是一個 DOM element - DOM element 是瀏覽器中的特殊 JavaScript 物件 - 與瀏覽器的渲染引擎有著緊密的連動 - 對 DOM 操作時渲染引擎將會自動重新繪製畫面 - 操作 DOM 效能成本昂貴 ---- DOM (Document Object Mode) ![dom](https://hackmd.io/_uploads/ry565p7OJx.png) <!-- 圖片來源:https://hsuchihting.github.io/javascript/20200615/1316819935/ --> ---- 前端效能優化的關鍵 -- 以「操作最小範圍的 DOM 來完成畫面所需的變動」 ---- ## Virtual DOM - 是一種程式設計概念,以「虛擬的畫面結構」資料來模擬期望的 DOM 畫面結構 - 與實際 DOM 保持對應關係 - 畫面結構同步化方向: Virtual DOM => 實際 DOM - JavaScript 物件,內容在描述期望的 DOM 結構樣子,本身也是樹狀結構的資料 ---- #### Virtual DOM ![virtual-dom-示意圖](https://hackmd.io/_uploads/Hyd7J0mdkx.png) ---- #### 實際 DOM ![實際 DOM](https://hackmd.io/_uploads/B1Z_eA7Oyx.png) ---- ### 畫面更新策略 Virtual DOM 是試做品,DOM 是成品 1. 「完整」產生新的對應畫面的 Virtual DOM 結構 2. 比較新版的 Virtual DOM 跟舊版的 Virtual DOM 之間的差異 3. 兩者差異即為本次更新「真正需操作 DOM 的部分」 4. 「操作最小範圍的 DOM 來完成畫面所需的變動」 ---- ![react](https://hackmd.io/_uploads/B19FQAmOke.png) ---- ### 畫面更新策略 - 找到「最低成本的 DOM 操作範圍」來達到效能上的優化 - Virtual DOM 的畫面結構資料並沒有與瀏覽器渲染引擎直接的綁定 - 產生、比較新舊版 Virtual DOM 也是會產生效能成本 - Virtual DOM 畫面結構的產生 & 比較都只是 「JavaScript 物件資料」因此在大範圍的變動還是相對的能帶來優化效能的效果。 ---- #### 觀念檢測 1. DOM 是什麼? 為什麼操作 DOM 是一種效能成本昂貴的操作? 2. Virtual DOM 是什麼? 與 DOM 的關係是? 3. Virtual DOM 為什麼可以幫助解決頻繁或大範圍的畫面變動時帶來的效能浪費? --- #### 2-2 建構畫面的最小單位:React element --- ## React element ---- ## React element? - React 基於實踐 Virtual DOM 概念所實作的虛擬畫面結構元素 - 是一種JavaScript 物件,用於描述預期的 DOM element 樣子 - 在 React 中實做的 Virtual DOM 畫面結構裡的每個元素都稱為「React element」 ---- ### React element - Virtual DOM 畫面結構中的其中一個元素 - 轉換成 DOM element 只是普通的 JavaScript 物件 --- ### React element: 描述畫面的最小單位 - component: - 非畫面最小單位 - 資料狀態與畫面更新機制的最小切分單位 - 可重用的畫面區塊,由數個 React element 組成 ---- #### createElement - 建立 React element 的方法 單一 React element: ![createElement](https://hackmd.io/_uploads/HJPHxgIuke.png) ---- #### React element 也可以是巢狀的樹狀結構 ![樹狀結構](https://hackmd.io/_uploads/r1CpYfIdkx.png) ---- #### 轉換後,實際 DOM <img height='450px' src="https://hackmd.io/_uploads/Symc5f8Oyg.png"/> ---- #### 為什麼 React element 建立之後就不可修改? - Virtual DOM 的概念在 React 實作中就是 React element 來實踐,用來「描述某個時間點版本的畫面結構」 - 比較新舊版 Virtual DOM 的差異,找出實際應該被更新的部分 - React 保護核心運作機制,因此不允許修改已建立的 React element --- #### React element 與 DOM Element 屬性對應性差異 - attribute & property 改以 camel case 命名: - onclick ⇨ onClick - inline styles 的 style 屬性內容格式不同: - HTML style 字串 ⇨ 物件形式表示 ``` style="border: 1px solid red;" ``` ``` style={{border: '1px solid red'}} ``` - JavaScript 保留字: - class ⇨ className - `<label>` for 屬性 ⇨ htmlFor --- #### 觀念檢測 1. React element 是什麼? 與 Virtual DOM 的關係為何? 與實際 DOM 的關係為何? 2. 為什麼 React element 一旦被建立後就無法被修改? --- #### 2-3 Render React element ---- #### React DOM 與 root <!-- #### React 是如何把 React element 轉換成實際 DOM element 並且重繪製到畫面上的? --> ---- ### Virtual DOM 轉換成 DOM 的過程 「指定瀏覽器畫面的特定區塊,讓 React 對其有管轄權. 以持續進行 Virtual DOM => DOM 的單向轉換與同步化的過程」 ---- #### 一. 準備輸出實際 DOM 結果的容器 ![index.html](https://hackmd.io/_uploads/Hyb0-XDdJg.png) ---- #### 二. 建立 root 並指定目標容器 ![截圖 2025-01-29 上午11.43.07](https://hackmd.io/_uploads/S1mJNmPOJx.png) ---- #### 三. 準備描述畫面的 React element ![截圖 2025-01-29 上午11.54.44](https://hackmd.io/_uploads/rJJT87Ddkl.png) ---- #### 四. 以建立好的 root 將 React element 轉換成實際的 DOM ![截圖 2025-01-29 上午11.55.22](https://hackmd.io/_uploads/Bk_RLXv_yl.png) ---- #### 畫面結果 React element 產生的 DOM element 被注入至指定的目標容器內 ![截圖 2025-01-29 上午11.52.53](https://hackmd.io/_uploads/BJwwwQvOkl.png) ---- #### 補充說明(1) 1. 若 root 容器含有非 React 產生的 DOM 內容會怎麼樣? Ans: 會被 React Element 產生的 DOM element 覆蓋掉 2. root 只能有一個嗎? Ans: 可以有多個,但在 SPA 的應用程式建議用一個 React root 管裡 ---- #### 補充說明(2) 3. 為什麽不能直接用 `document.body ` 作為 root 容器? Ans: 因許多第三方套件會對 body 操作或修改,會造成 React 對 DOM element 控制管理不穩定 ---- #### React 只會操作真正需要被更新的 DOM element - 新的 React element 產生之後,交由 React-dom 處理 - 比較新舊 React element 的結構差異之處,只更新差異處的 DOM element ---- #### 因此,使用 React 開發時的效能優化關鍵: 1. 避免不必要的 React element 產生動作 2. 部分畫面沒有更新需求時,重用舊有的 React element 開發者只需要著重於 React element 管理 ---- #### 重繪製畫面管理流程:Reconciler 與 renderer - Reconciler: - 定義&產生新的 React element - 比較新舊 React element 差異之處 - 負責找出 UI 變更,確定哪些部分需要更新。 - Renderer: - 將畫面描述的結構繪製成實際的 DOM - 將在 reconciler 階段比較完畢的新舊差異之處,同步至實際的 DOM ---- #### 分成兩階段處理的好處是什麼? - 解耦 UI 計算與實際渲染,不依賴特定渲染方式 - 不同環境可以共用 Reconciler,而 Renderer 可以彈性替換成其他環境的 UI 畫面 - 「learn once write anywhere 」 - 其他 Renderer: react-dom、React Native ---- #### 觀念檢測 1. `react-dom` 是什麼? Root 是什麽? 2. 解釋 React DOM 繪製成實際 DOM 的流程以及每個步驟的意義 3. React 怎麽做到只操作那些需要被更新的 DOM element? 4. React 將「定義以及管理畫面結構的描述(reconciler)」和「將畫面結構描述製成實際畫面成品(renderder)」拆分成兩階段處理,這樣設計有什麼好處? --- #### 討論 Q&A --- #### 感謝聆聽 --- #### 2/18 - 導讀人 - 筆記工
{"description":"自我介紹","title":"React 思維進化 2-1~2-3","contributors":"[{\"id\":\"8c1b4838-86f3-430e-9300-fea6810bc261\",\"add\":8670,\"del\":3263}]"}
    94 views