日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

diff算法的作用

計算出Virtual DOM中真正變化的部分,并只針對該部分進行原生DOM操作,而非重新渲染整個頁面。

傳統diff算法

通過循環遞歸對節點進行依次對比,算法復雜度達到 O(n^3) ,n是樹的節點數,這個有多可怕呢?——如果要展示1000個節點,得執行上億次比較。。即便是CPU快能執行30億條命令,也 很難在一秒內 計算出差異。

react的diff算法

diff算法是調和的具體實現。

調和:將Virtual DOM樹轉換成actual DOM樹的最少操作的過程 稱為 調和 。

diff策略

React用 三大策略 將O(n^3)復雜度 轉化為 O(n)復雜度

策略一( tree diff ):

Web UI中DOM節點跨層級的移動操作特別少,可以忽略不計。

策略二( component diff ):

擁有相同類的兩個組件 生成相似的樹形結構,

擁有不同類的兩個組件 生成不同的樹形結構。

策略三( element diff ):

對于同一層級的一組子節點,通過唯一id區分。

tree diff算法

(1)React通過updateDepth對Virtual DOM樹進行 層級控制 。

(2)對樹分層比較,兩棵樹 只對 同一層次節點 進行比較。如果該節點不存在時,則該節點及其子節點會被完全刪除,不會再進一步比較。

(3)只需遍歷一次,就能完成整棵DOM樹的比較。

diff算法介紹

 

對于策略一,React 對樹進行了分層比較,兩棵樹只會對同一層次的節點進行比較。

只會對相同層級的 DOM 節點進行比較,當發現節點已經不存在時,則該節點及其子節點會被完全刪除,不會用于進一步的比較。

如果出現了 DOM 節點跨層級的移動操作。

如上圖這樣,A節點就會被直接銷毀了。

Diif 的執行情況是:create A -> create C -> create D -> delete A

component diff

React對不同的組件間的比較,有三種策略

(1)同一類型的兩個組件,按原策略(層級比較)繼續比較Virtual DOM樹即可。

(2)同一類型的兩個組件,組件A變化為組件B時,可能Virtual DOM沒有任何變化,如果知道這點(變換的過程中,Virtual DOM沒有改變),可節省大量計算時間,所以 用戶 可以通過 shouldComponentUpdate() 來判斷是否需要 判斷計算。

(3)不同類型的組件,將一個(將被改變的)組件判斷為dirty component(臟組件),從而 替換 整個組件的所有節點 。

注意:如果組件D和組件G的結構相似,但是 React判斷是 不同類型的組件,則不會比較其結構,而是刪除 組件D及其子節點,創建組件G及其子節點。

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進行區分,移動即可。

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進行區分,移動即可。

移動的條件:

  • 對新集合中的節點進行循環遍歷,新舊集合中是否存在相同節點
  • nextIndex: 新集合中當前節點的位置
  • lastIndex: 訪問過的節點在舊集合中最右的位置(最大位置)
  • If (child._mountIndex < lastIndex)

情形一:新舊集合中存在相同節點但位置不同時,如何移動節點

diff算法介紹

 

(1)看著上圖的 B,React先從新中取得B,然后判斷舊中是否存在相同節點B,當發現存在節點B后,就去判斷是否移動B。

B在舊 中的index=1,它的lastIndex=0, 不滿足 index < lastIndex 的條件,因此 B 不做移動操作。此時,一個操作是,lastIndex=(index,lastIndex)中的較大數=1.

注意:lastIndex有點像浮標,或者說是一個map的索引,一開始默認值是0,它會與map中的元素進行比較,比較完后,會改變自己的值的(取index和lastIndex的較大數)。

(2)看著 A,A在舊的index=0,此時的lastIndex=1(因為先前與新的B比較過了), 滿足index<lastIndex ,因此,對A進行移動操作,此時 lastIndex=max(index,lastIndex)=1

(3)看著D,同(1),不移動,由于D在舊的index=3,比較時,lastIndex=1,所以改變lastIndex=max(index,lastIndex)=3

(4)看著C,同(2),移動,C在舊的index=2,滿足index<lastIndex(lastIndex=3),所以移動。

由于C已經是最后一個節點,所以diff操作結束。

情形二:新集合中有新加入的節點,舊集合中有刪除的節點

diff算法介紹

 

(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操作結束。

diff的不足與待優化的地方

diff算法介紹

 

看圖的 D,此時D不移動,但它的index是最大的,導致更新lastIndex=3,從而使得其他元素A,B,C的index<lastIndex,導致A,B,C都要去移動。

理想情況是只移動D,不移動A,B,C。因此,在開發過程中,盡量減少類似將最后一個節點移動到列表首部的操作,當節點數量過大或更新操作過于頻繁時,會影響React的渲染性能。

分享到:
標簽:算法 diff
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定