
- ReactJS 教程
- ReactJS - 首頁
- ReactJS - 簡介
- ReactJS - 路線圖
- ReactJS - 安裝
- ReactJS - 特性
- ReactJS - 優點與缺點
- ReactJS - 架構
- ReactJS - 建立 React 應用
- ReactJS - JSX
- ReactJS - 元件
- ReactJS - 巢狀元件
- ReactJS - 使用新建立的元件
- ReactJS - 元件集合
- ReactJS - 樣式
- ReactJS - 屬性 (props)
- ReactJS - 使用屬性建立元件
- ReactJS - props 驗證
- ReactJS - 建構函式
- ReactJS - 元件生命週期
- ReactJS - 事件管理
- ReactJS - 建立一個事件感知元件
- ReactJS - 在 Expense Manager 應用中引入事件
- ReactJS - 狀態管理
- ReactJS - 狀態管理 API
- ReactJS - 無狀態元件
- ReactJS - 使用 React Hooks 進行狀態管理
- ReactJS - 使用 React Hooks 進行元件生命週期管理
- ReactJS - 佈局元件
- ReactJS - 分頁
- ReactJS - Material UI
- ReactJS - Http 客戶端程式設計
- ReactJS - 表單程式設計
- ReactJS - 受控元件
- ReactJS - 非受控元件
- ReactJS - Formik
- ReactJS - 條件渲染
- ReactJS - 列表
- ReactJS - Keys
- ReactJS - 路由
- ReactJS - Redux
- ReactJS - 動畫
- ReactJS - Bootstrap
- ReactJS - Map
- ReactJS - 表格
- ReactJS - 使用 Flux 管理狀態
- ReactJS - 測試
- ReactJS - CLI 命令
- ReactJS - 構建和部署
- ReactJS - 示例
- Hooks
- ReactJS - Hooks 簡介
- ReactJS - 使用 useState
- ReactJS - 使用 useEffect
- ReactJS - 使用 useContext
- ReactJS - 使用 useRef
- ReactJS - 使用 useReducer
- ReactJS - 使用 useCallback
- ReactJS - 使用 useMemo
- ReactJS - 自定義 Hooks
- ReactJS 高階
- ReactJS - 可訪問性
- ReactJS - 程式碼分割
- ReactJS - Context
- ReactJS - 錯誤邊界
- ReactJS - 轉發 Refs
- ReactJS - Fragments
- ReactJS - 高階元件
- ReactJS - 與其他庫整合
- ReactJS - 效能最佳化
- ReactJS - Profiler API
- ReactJS - Portals
- ReactJS - 無 ES6 ECMAScript 的 React
- ReactJS - 無 JSX 的 React
- ReactJS - 協調機制 (Reconciliation)
- ReactJS - Refs 和 DOM
- ReactJS - Render Props
- ReactJS - 靜態型別檢查
- ReactJS - Strict Mode
- ReactJS - Web Components
- 其他概念
- ReactJS - 日期選擇器
- ReactJS - Helmet
- ReactJS - 內聯樣式
- ReactJS - PropTypes
- ReactJS - BrowserRouter
- ReactJS - DOM
- ReactJS - 走馬燈
- ReactJS - 圖示
- ReactJS - 表單元件
- ReactJS - 參考 API
- ReactJS 有用資源
- ReactJS - 快速指南
- ReactJS - 有用資源
- ReactJS - 討論
ReactJS - 協調機制 (Reconciliation)
協調機制是 React 庫內部的一個流程。眾所周知,React 應用會建立一個虛擬 DOM,然後根據虛擬 DOM 更新應用的實際 DOM。每當 React 接收到更新請求時,它都會首先建立一個虛擬 DOM,然後使用不同的 diff 演算法將虛擬 DOM 與先前狀態進行比較,只有在絕對必要時,才會更新 DOM。
儘管 diff 演算法和更新 DOM 是 React 核心內部的,但瞭解一些內部機制將有助於我們調整應用,以最大限度地利用 React 庫。
Diff 演算法
本章讓我們瞭解 React 核心應用的一些 diff 演算法。
相同型別的元素
每當 React 元件將元素從一種型別更改為另一種型別(例如,從 div 更改為更具體的 p)時,整個 React 虛擬 DOM 樹都會發生更改,並觸發 DOM 更新。
<!-- Before --> <div> <Content /> </div> <!-- After --> <p> <Content /> </p>
此處,整個元素將被更新。
相同型別的 DOM 屬性。
當元素型別相同時,React 會檢查屬性是否存在差異。如果 React 發現屬性及其值的任何新更改,則它只會更新已更改的屬性。
<!-- Before --> <div className="someClass"> <Content /> </div> <!-- After --> <div className="someOtherClass"> <Content /> </div>
此處,只會更新 DOM 例項的 class 屬性。
相同型別的 DOM 屬性(樣式)。
當元素型別相同時,並且 React 發現樣式屬性存在差異時,它只會更新樣式的屬性。
<!-- Before --> <div style={{fontFamily: 'Arial'}} /> <p> ... </p> </div> <!-- After --> <div style={{color: 'red', fontFamily: 'Arial'}} /> <p> ... </p> </div>
此處,只會更新 div 元素樣式的 color 屬性。
相同型別的元件元素 - 每當 React 看到相同型別的 React 元件時,它都會呼叫元件的 componentWillUpdate 事件和其他更新事件以更新其狀態。然後,它將呼叫元件的 render 方法,演算法會遞迴。
相同型別的子元素集合 - 每當 React 看到相同型別的子元素集合時,它會按順序檢查元素是否存在差異。因此,如果我們有一個新的第一個子元素,則整個集合將被更新。
<!-- Before --> <ul> <li>Peter</li> <li>Olivia</li> </ul> <!-- After --> <ul> <li>John</li> <li>Peter</li> <li>Olivia</li> </ul>
由於第一個元素 (li) 已更新,因此此處將更新所有元素(ul 元素的子元素)。
為了解決這個問題,我們可以引入一個 key 屬性,如下面的程式碼片段所示。React 有一個專門為此目的的 key 屬性。
<!-- Before --> <ul> <li key="1">Peter</li> <li key="2">Olivia</li> </ul> <!-- After --> <ul> <li key="3">John</li> <li key="1">Peter</li> <li key="2">Olivia</li> </ul>
總結
React 嘗試在每個版本中最佳化 diff 演算法,以確保更新次數最少。更新次數越少,應用程式的效能越好。瞭解內部機制並遵循最佳實踐進行編碼,我們可以成倍地提高應用程式的效能。