Vue中的diff算法?vue
概念: diff算法是一種優化手段,將先後兩個模塊進行差別對比,修補(更新)差別的過程叫作patch(打補丁)
爲何vue,react這些框架中都會有diff算法呢? 咱們都知道渲染真實dom的開銷是很大的,這個跟性能優化中的重繪重排意義相似, 回到正題來, 有時候咱們修改了頁面中的某個數據,若是直接渲染到真實DOM中會引發整棵數的重繪重排, 那麼咱們能不能只讓咱們修改的數據映射到真實DOM, 作一個最少化重繪重排呢,說到這裏你應該對爲何使用diff算法有一個簡單的概念了node
一句話歸納吧,virtual DOM是將真實的DOM的數據抽取出來,以對象的形式模擬樹形結構, diff 算法比較的也是virtual DOMreact
代碼理解git
<div> <p>JS每日一題</p> </div> // 轉換成VNode 相似於下面這種 const Vnode = { tag: 'div', children: [ { tag: 'p', text: 'JS每日一題' } ] };
源碼太多了,就不貼了, 有興趣的能夠本身看看 https://github.com/vuejs/vue/...
簡單的說就是新舊虛擬dom 的比較,若是有差別就以新的爲準,而後再插入的真實的dom中,從新渲染github
特色算法
比較後幾種狀況性能優化
if (oldVnode === vnode)
,他們的引用一致,能夠認爲沒有變化。if(oldVnode.text !== null && vnode.text !== null && oldVnode.text !== vnode.text)
,文本節點的比較,須要修改,則會調用Node.textContent = vnode.text
。if( oldCh && ch && oldCh !== ch )
, 兩個節點都有子節點,並且它們不同,這樣咱們會調用updateChildren
函數比較子節點,這是diff的核心else if (ch)
,只有新的節點有子節點,調用createEle(vnode)
,vnode.el
已經引用了老的dom節點,createEle
函數會在老dom節點上添加子節點。else if (oldCh)
,新節點沒有子節點,老節點有子節點,直接刪除老節點。設置key和不設置key的區別:
不設key,newCh和oldCh只會進行頭尾兩端的相互比較,設key後,除了頭尾兩端的比較外,還會從用key生成的對象oldKeyToIdx
中查找匹配的節點,因此爲節點設置key能夠更高效的利用dom框架
如咱們但願能夠在B和C之間加一個F,Diff算法默認執行起來是這樣的:dom
即把C更新成F,D更新成C,E更新成D,最後再插入E,是否是很沒有效率?函數
因此咱們須要使用key來給每一個節點作一個惟一標識,Diff算法就能夠正確的識別此節點,找到正確的位置區插入新的節點。
因此一句話,key的做用主要是爲了高效的更新虛擬DOM。另外vue中在使用相同標籤名元素的過渡切換時,也會使用到key屬性,其目的也是爲了讓vue能夠區分它們,不然vue只會替換其內部屬性而不會觸發過渡效果
JS每日一題能夠當作是一個語音答題社區
天天利用碎片時間採用60秒內的語音形式來完成當天的考題
羣主在第二天0點推送當天的參考答案