【Vue原理】Diff - 白話版

寫文章不容易,點個讚唄兄弟


專注 Vue 源碼分享,文章分爲白話版和 源碼版,白話版助於理解工作原理,源碼版助於瞭解內部詳情,讓我們一起學習吧
研究基於 Vue版本 【2.5.17】

如果你覺得排版難看,請點擊 下面鏈接 或者 拉到 下面關注公衆號也可以吧

【Vue原理】Diff - 白話版

終於到了最後一塊內容了!今天我們就來簡單概括一下 Diff,內容一點都不多哦,全是圖片

Diff 作爲 Vue 比較重要的一部分內容,還是非常有必要深入瞭解的

此篇文章就會分幾塊內容進行簡單闡述,不會出現任何的源碼,只是爲了幫助大家建立一種思路,瞭解下 Diff 的大概內容

1、Diff 的作用

2、Diff 的做法

3、Diff 的比較邏輯

4、簡單的例子

下面就開始我們的正文


Diff 作用

Diff 的出現,就會爲了減少更新量,找到最小差異部分DOM,只更新差異部分DOM就好了

這樣消耗就會小一些

數據變化一下,沒必要把其他沒有涉及的沒有變化的DOM 也替換了


Diff 做法

Vue 只會對新舊節點中 父節點是相同節點 的 那一層子節點 進行比較

也可以說成是

只有兩個新舊節點是相同節點的時候,纔會去比較他們各自的子節點

最大的根節點一開始可以直接比較

這也叫做 同層級比較,並不需要遞歸,雖然好像降低了一些複用性,也是爲了避免過度優化,是一種很高效的 Diff 算法

新舊節點是什麼

所有的 新舊節點 指的都是 Vnode 節點,Vue 只會比較 Vnode 節點,而不是比較 DOM

因爲 Vnode 是 JS 對象,不受平臺限制,所以以它作爲比較基礎,代碼邏輯後期不需要改動

拿到比較結果後,根據不同平臺調用相應的方法進行處理就好了

想了解 Vnode 更多信息可以轉到這篇文章 VNode - 源碼版

父節點是相同節點是什麼意思?

比如下圖出現的 四次比較(從 first 到 fouth),他們的共同特點都是有 相同的父節點

比如 藍色方的比較,新舊子節點的父節點是相同節點 1

比如 紅色方的比較,新舊子節點的父節點都是 2

所以他們纔有比較的機會

公衆號

而下圖中,只有兩次比較,就是因爲在 藍色方 比較中,並沒有相同節點,所以不會再進行下級子節點比較

公衆號


Diff 比較邏輯

Diff 比較的內核是 節點複用,所以 Diff 比較就是爲了在 新舊節點中 找到 相同的節點

這個的比較邏輯是建立在上一步說過的同層比較基礎之上的

所以說,節點複用,找到相同節點並不是無限制遞歸查找

比如下圖中,的確 舊節點樹 和 新節點樹 中有相同節點 6,但是然並卵,舊節點6並不會被複用

公衆號

就算在同一層級,然而父節點不一樣,依舊然並卵

公衆號

只有這種情況的節點會被複用,相同父節點 8

公衆號

下面說說 Diff 的比較邏輯

1、能不移動,儘量不移動

2、沒得辦法,只好移動

3、實在不行,新建或刪除

比較處理流程是下面這樣

在新舊節點中

1、先找到 不需要移動的相同節點,消耗最小

2、再找相同但是需要移動的節點,消耗第二小

3、最後找不到,纔會去新建刪除節點,保底處理

比較是爲了修改DOM 樹

其實這裏存在 三種樹,一個是 頁面DOM 樹,一個是 舊VNode 樹,一個是 新 Vnode 樹

頁面DOM 樹 和 舊VNode 樹 節點一一對應的

而 新Vnode 樹則是表示更新後 頁面DOM 樹 該有的樣子

這裏把 舊Vnode 樹 和 新Vnode樹 進行比較的過程中

不會對這兩棵Vode樹進行修改,而是以比較的結果直接對 真實DOM 進行修改

比如說,在 舊 Vnode 樹同一層中,找到 和 新Vnode 樹 中一樣但位置不一樣節點

此時需要移動這個節點,但是不是移動 舊 Vnode 樹 中的節點

而是 直接移動 DOM

總的來說,新舊 Vnode 樹是拿來比較的,頁面DOM 樹是拿來根據比較結果修改的

如果你有點懵,我們就來就簡單說個例子


Diff 簡單例子

比如下圖存在這兩棵 需要比較的新舊節點樹 和 一棵 需要修改的頁面 DOM樹

公衆號

第一輪比較開始

因爲父節點都是 1,所以開始比較他們的子節點

按照我們上面的比較邏輯,所以先找 相同 && 不需移動 的點

毫無疑問,找到 2

公衆號

拿到比較結果,這裏不用修改DOM,所以 DOM 保留在原地

公衆號

第二輪比較開始

然後,沒有 相同 && 不需移動 的節點 了

只能第二個方案,開始找相同的點

找到 節點5,相同但是位置不同,所以需要移動

公衆號

拿到比較結果,頁面 DOM 樹需要移動DOM 了,不修改,原樣移動

公衆號

第三輪比較開始

繼續,哦吼,相同節點也沒得了,沒得辦法了,只能創建了

所以要根據 新Vnode 中沒找到的節點去創建並且插入

然後舊Vnode 中有些節點不存在 新VNode 中,所以要刪除

公衆號

於是開始創建節點 6 和 9,並且刪除節點 4 和 5

公衆號

然後頁面就完成更新啦

怎麼樣,有沒有感興趣,感興趣就看源碼吧哈哈

後面的就會出源碼版啦

最後

鑑於本人能力有限,難免會有疏漏錯誤的地方,請大家多多包涵,如果有任何描述不當的地方,歡迎後臺聯繫本人,有重謝

公衆號

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章