react的diff方法可用於找出兩個物件之間的差異,目的是盡可能做到節點復用;diff演算法是調和的具體實現,而調和是指將Virtual DOM樹轉換成Actual DOM樹的最少操作的過程。
本教學操作環境:Windows10系統、react18.0.0版、Dell G3電腦。
react的diff方法是什麼?
一、Diff演算法的作用
渲染真實DOM的開銷很大,有時候我們修改了某個數據,直接渲染到真實dom上會造成整個dom樹的重繪和重排。我們希望只更新我們修改的那一小塊dom,而不是整個dom,diff演算法就幫我們實現了這一點。
diff演算法的本質是:找出兩個物件之間的差異,目的是盡可能做到節點重複使用。
附註:此處所說的對象,指的其實就是vue中的virtual dom(虛擬dom樹),也就是使用js物件來表示頁中的dom結構。
二、React的Diff演算法
#1、 什麼是調和?
#將Virtual DOM樹轉換成Actual DOM樹的#最少操作的過程稱為調和。
2、什麼是React diff演算法?
#diff演算法是調和的具體實作。
3、diff策略
React用三大策略將O(n3)複雜度轉換成 O(n)複雜度
(1) #策略一(#tree diff):Web UI中DOM節點跨層級的行動操作特別少,可以忽略不計。
#(2)策略二(component diff):有相同類別的兩個元件產生相似的樹狀結構,有兩個不同類別的元件產生不同的樹狀結構。
#(3)策略三(
##element diff):對於同一層級的一組子節點,透過唯一id區分。
4、tree diff:(1)React透過updateDepth對Virtual DOM樹進行層級控制
#。
(2)對樹分層比較,兩棵樹只對
##同一層次節點
###進行比較。如果該節點不存在時,則該節點及其子節點會被完全刪除,不會再進一步比較。 ##################(3)只要遍歷一次,就能完成整棵DOM樹的比較。 #####################如果DOM 節點出現了跨層級操作,Diff會怎麼做? ############### 答:Tree DIFF是對樹的每一層進行遍歷,如果某組件不存在了,則會直接銷毀。如圖所示,左邊是舊屬,右邊是新屬,第一層是R組件,一模一樣,不會發生變化;第二層進入Component DIFF,同一類型組件繼續比較下去,發現A組件沒有,所以直接刪除A、B、C元件;繼續第三層,重新建立A、B、C元件。 ############### ######如上圖所示,以A為根節點的整棵樹會被重新創建,而不是移動,因此 官方建議不要進行DOM節點跨層級操作,可透過CSS隱藏、顯示節點,而不是真正移除、新增DOM節點。 ########################5、component diff :##################### #########React對不同的元件間的比較,有三種策略########################(1)相同類型的兩個元件,按原策略(層級比較)繼續比較Virtual DOM樹即可。 ##########(2)同一類型的兩個元件,元件A變化為元件B時,可能Virtual DOM沒有任何變化,如果知道這點(變換的過程中,Virtual DOM沒有改變),可節省大量運算時間,所以使用者可以透過shouldComponentUpdate() 來判斷是否需要判斷計算。
(3)不同類型的元件,將一個(將被改變的)元件判斷為dirtycomponent(髒元件),從而取代整個元件的所有節點。
#注意:##如上圖所示,當元件D變成元件G時,即使這兩個元件結構相似,一旦React判斷D和G是不用型別的元件,就不會比較兩者的結構,而是直接刪除組件D,重新建立組件G及其子節點。 雖然當兩個元件是不同類型但結構相似時,進行diff演算法分析會影響效能,但是畢竟不同類型的元件存在相似DOM樹的情況在實際開發過程中很少出現,因此這種極端因素很難在實際開發過程中造成重大影響。
6、element diff
當節點處於相同層級時,diff提供三種節點運算:刪除、插入、移動。
插入
#:
元件C 不在集合(A,B)中,需要插入
刪除:#(1)元件D 在集合中(A, B,D)中,但D的節點已經更改,不能重複使用更新,所以需要刪除舊的D ,再建立新的。
(2)元件D之前在集合(A,B,D)中,但集合變成新的集合(A,B)了,D就需要刪除。 移動:元件D已經在集合( A,B,C,D)裡了,且集合更新時,D沒有發生更新,只是位置改變,如新集合(A,D,B,C),D在第二個,無須像傳統diff,讓舊集合的第二個B和新集合的第二個D 比較,並且刪除第二個位置的B,再在第二個位置插入D,而是(對同一層級的同組子節點) 新增唯一key進行區分,移動即可。
移動######################## 情形一:########################當新舊集合中存在相同節點但位置不同時,如何移動節點########## #####
(1)B不移動,不贅述,更新l astIndex=1
(2)新集合取得E,發現舊不存在,故在lastIndex=1的位置建立E,更新lastIndex=1
(3)新集合取得C,C不移動,更新lastIndex=2
#(4)新集合取得A,A移動,同上,更新lastIndex=2
(5)新集合對比後,再對舊集合遍歷。判斷 新集合 沒有,但 舊集合 有的元素(如D,新集合沒有,舊集合有),發現 D,刪除D,diff操作結束。
React中Diff演算法實現的程式碼:
_updateChildren: function(nextNestedChildrenElements, transaction, context) { var prevChildren = this._renderedChildren; var removedNodes = {}; var mountImages = []; // 获取新的子元素数组 var nextChildren = this._reconcilerUpdateChildren( prevChildren, nextNestedChildrenElements, mountImages, removedNodes, transaction, context ); if (!nextChildren && !prevChildren) { return; } var updates = null; var name; var nextIndex = 0; var lastIndex = 0; var nextMountIndex = 0; var lastPlacedNode = null; for (name in nextChildren) { if (!nextChildren.hasOwnProperty(name)) { continue; } var prevChild = prevChildren && prevChildren[name]; var nextChild = nextChildren[name]; if (prevChild === nextChild) { // 同一个引用,说明是使用的同一个component,所以我们需要做移动的操作 // 移动已有的子节点 // NOTICE:这里根据nextIndex, lastIndex决定是否移动 updates = enqueue( updates, this.moveChild(prevChild, lastPlacedNode, nextIndex, lastIndex) ); // 更新lastIndex lastIndex = Math.max(prevChild._mountIndex, lastIndex); // 更新component的.mountIndex属性 prevChild._mountIndex = nextIndex; } else { if (prevChild) { // 更新lastIndex lastIndex = Math.max(prevChild._mountIndex, lastIndex); } // 添加新的子节点在指定的位置上 updates = enqueue( updates, this._mountChildAtIndex( nextChild, mountImages[nextMountIndex], lastPlacedNode, nextIndex, transaction, context ) ); nextMountIndex++; } // 更新nextIndex nextIndex++; lastPlacedNode = ReactReconciler.getHostNode(nextChild); } // 移除掉不存在的旧子节点,和旧子节点和新子节点不同的旧子节点 for (name in removedNodes) { if (removedNodes.hasOwnProperty(name)) { updates = enqueue( updates, this._unmountChild(prevChildren[name], removedNodes[name]) ); } } }
三、基於Diff的開發建議
基於tree diff:
- 開發元件時,請注意保持DOM結構的穩定;即,盡可能少地動態操作DOM結構,尤其是移動操作。
- 當節點數過大或頁面更新次數過多時,頁面卡頓的現象會比較明顯。
- 這時可以透過 CSS 隱藏或顯示節點,而不是真的移除或新增 DOM 節點。
基於component diff:
- #注意使用 shouldComponentUpdate() 來減少元件不必要的更新。
- 對於類似的結構應該盡量封裝成元件,既減少程式碼量,又能減少component diff的效能消耗。
基於element diff:
- 對於列表結構,盡量減少類似將最後一個節點移動到列表首部的操作,當節點數量過大或更新操作過於頻繁時,在一定程度上會影響React 的渲染效能。
推薦學習:《react影片教學》
以上是react的diff方法是什麼的詳細內容。更多資訊請關注PHP中文網其他相關文章!

HTML與React可以通過JSX無縫整合,構建高效的用戶界面。 1)使用JSX嵌入HTML元素,2)利用虛擬DOM優化渲染性能,3)通過組件化管理和渲染HTML結構。這種整合方式不僅直觀,還能提升應用性能。

React通過state和props高效渲染數據,並通過合成事件系統處理用戶事件。 1)使用useState管理狀態,如計數器示例。 2)事件處理通過在JSX中添加函數實現,如按鈕點擊。 3)渲染列表需使用key屬性,如TodoList組件。 4)表單處理需使用useState和e.preventDefault(),如Form組件。

React通過HTTP請求與服務器交互,實現數據的獲取、發送、更新和刪除。 1)用戶操作觸發事件,2)發起HTTP請求,3)處理服務器響應,4)更新組件狀態並重新渲染。

React是一種用於構建用戶界面的JavaScript庫,通過組件化開發和虛擬DOM提高效率。 1.組件與JSX:使用JSX語法定義組件,增強代碼直觀性和質量。 2.虛擬DOM與渲染:通過虛擬DOM和diff算法優化渲染性能。 3.狀態管理與Hooks:Hooks如useState和useEffect簡化狀態管理和副作用處理。 4.使用示例:從基本表單到高級的全局狀態管理,使用ContextAPI。 5.常見錯誤與調試:避免狀態管理不當和組件更新問題,使用ReactDevTools調試。 6.性能優化與最佳

reactisafrontendlibrary,focusedonBuildingUserInterfaces.itmanagesuistateandupdatesefficefited avelyuseVirusity diftualdom,and internactSwithBackendServIcesViaApisforDatahandling,butdoesnotprocessorcorsorsorstoredordordordoredairself。

React可以嵌入到HTML中來增強或完全重寫傳統的HTML頁面。 1)使用React的基本步驟包括在HTML中添加一個根div,並通過ReactDOM.render()渲染React組件。 2)更高級的應用包括使用useState管理狀態和實現複雜的UI交互,如計數器和待辦事項列表。 3)優化和最佳實踐包括代碼分割、惰性加載和使用React.memo和useMemo來提高性能。通過這些方法,開發者可以利用React的強大功能來構建動態和響應迅速的用戶界面。

React是構建現代前端應用的JavaScript庫。 1.它採用組件化和虛擬DOM優化性能。 2.組件使用JSX定義,狀態和屬性管理數據。 3.Hooks簡化生命週期管理。 4.使用ContextAPI管理全局狀態。 5.常見錯誤需調試狀態更新和生命週期。 6.優化技巧包括Memoization、代碼拆分和虛擬滾動。

React的未來將專注於組件化開發的極致、性能優化和與其他技術棧的深度集成。 1)React將進一步簡化組件的創建和管理,推動組件化開發的極致。 2)性能優化將成為重點,特別是在大型應用中的表現。 3)React將與GraphQL和TypeScript等技術深度集成,提升開發體驗。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

EditPlus 中文破解版
體積小,語法高亮,不支援程式碼提示功能

SublimeText3 英文版
推薦:為Win版本,支援程式碼提示!

MinGW - Minimalist GNU for Windows
這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。