簡述 Diff 演算法的執行過程

2021-10-21 20:56:56 字數 1257 閱讀 8119

diff演算法是一種通過同層的樹節點進行比較的高效演算法,避免了對樹進行逐層搜尋遍歷,所以時間複雜度只有 o(n)。

diff演算法有兩個比較顯著的特點:

1、比較只會在同層級進行, 不會跨層級比較。

2、在diff比較的過程中,迴圈從兩邊向中間收攏。

首先定義 oldstartidx、newstartidx、oldendidx 以及 newendidx 分別是新老兩個 vnode 的兩邊的索引。

接下來是乙個 while 迴圈,在這過程中,oldstartidx、newstartidx、oldendidx 以及 newendidx 會逐漸向中間靠攏。while 迴圈的退出條件是直到老節點或者新節點的開始位置大於結束位置。

while 迴圈中會遇到四種情況:

情形一:當新老 vnode 節點的 start 是同一節點時,直接 patchvnode 即可,同時新老 vnode 節點的開始索引都加 1。

情形二:當新老 vnode 節點的 end 是同一節點時,直接 patchvnode 即可,同時新老 vnode 節點的結束索引都減 1。

情形三:當老 vnode 節點的 start 和新 vnode 節點的 end 是同一節點時,這說明這次資料更新後 oldstartvnode 已經跑到了 oldendvnode 後面去了。這時候在 patchvnode 後,還需要將當前真實 dom 節點移動到 oldendvnode 的後面,同時老 vnode 節點開始索引加 1,新 vnode 節點的結束索引減 1。

情形四:當老 vnode 節點的 end 和新 vnode 節點的 start 是同一節點時,這說明這次資料更新後 oldendvnode 跑到了 oldstartvnode 的前面去了。這時候在 patchvnode 後,還需要將當前真實 dom 節點移動到 oldstartvnode 的前面,同時老 vnode 節點結束索引減 1,新 vnode 節點的開始索引加 1。

while 迴圈的退出條件是直到老節點或者新節點的開始位置大於結束位置。

情形一:如果在迴圈中,oldstartidx大於oldendidx了,那就表示oldchildren比newchildren先迴圈完畢,那麼newchildren裡面剩餘的節點都是需要新增的節點,把[newstartidx, newendidx]之間的所有節點都插入到dom中

情形二:如果在迴圈中,newstartidx大於newendidx了,那就表示newchildren比oldchildren先迴圈完畢,那麼oldchildren裡面剩餘的節點都是需要刪除的節點,把[oldstartidx, oldendidx]之間的所有節點都刪除

diff程式的演算法

diff程式很重要,linux中的源 補丁都是diff作出來的,diff在比較兩個文字檔案的不同方面很高效,它是基於行的,diff會將兩個檔案都按照行分成若干部分,然後計算這些行每一行的校驗碼,之後的問題就是比較這兩個檔案的所有行的校驗碼序列的不同了,這就把問題歸結為了序列比對,diff用的是動態規...

vue的diff演算法

1.當資料發生變化時,vue是怎麼更新節點的?渲染真實dom的開銷很大,比如我們修改了某個資料,如果直接渲染到真實dom會引起整個dom樹的重繪和重排,有沒有可能我們只更新我們修改的那一小塊dom而不更新整個dom呢?diff演算法可以幫助我們。我們根據真實dom生成乙個虛擬dom,當虛擬dom某個...

React的Diff演算法

要掌握react的diff演算法我們必須先了解一下其渲染的機制 在每一次的狀態或者屬性更新的時候,react元件的render方法會進行渲染,返回乙個虛擬dom物件,這個就是react的渲染機制。但是這裡就有個問題,每次生成新的dom結構,也還是要轉化為真實的dom,還是會帶來大量的真實dom的操作...