snabbdom
本文的snabbdom源碼剖析採納的是0.54版本(即未用ts重寫前的末了一版)
前期相識
snabbdom被用作vue的假造dom。本文的一個目標就是關於進入vue源碼準備。
本文大抵解說,而不會完整細化至代碼行數解說
文件(以下只指出須要瀏覽的重要文件)
- modules
- helper
- h.js
- htmldomapi.js
- is.js
- snabbdom.js
- thunk.js
- vnode.js
vnode.js
說白了就是返回一個數據示意dom構造的數據對象
h.js
則是對多重有子構造 text節點之類的數據對象舉行在再處置懲罰
返回一個剖析好的vnode
htmltoapi
一些dom操縱的api封裝
連繫到背面做vnode襯着到實在dom的操縱
is.js 兩個東西函數 一個是是不是為數組 一個是是不是為基礎範例 也就是数字string這些文本節點
modules
內里放的則是一些對應的數據構造上比方property attribute之類的輔佐操縱
- attributes
內里用來更新節點的屬性
基礎的套路都是一個for in迭代 然後內部推斷patch 推斷是不是須要更新亦或許是刪除 假如存在屬性的話 且差別肯定是更新 假如新有了 舊的沒有就增添 新沒有了舊另有 關於一些屬性直接設置false 或許是賦空即可
- class.js
這裏也是一些應用classList做疾速增添修正刪除節點上的class的操縱
基礎簡樸的推斷就是這類套路
- datatset
設置節點屬性值
- eventlistener
看源碼可以發明 事宜綁定這一步傳入的參數實際上是被包裝的
應用函數封裝了一層handleevent
handleevent內里實際上是觸發invokeHandler
那末從源碼可以看出 實際上觸發dom節點的綁定事宜實際上是在觸發
綁定在上下文為vnode的觸發器上。
props設置節點這個props是須要鍵值對的。平常自定義屬性值在這裏聲明好一些,設置checked selected由於內部有一個booleanarray 實在有綁定的話只是做
property可以從attribute中獲得同步;
attribute不會同步property上的值;
style.js
模仿動畫幀 用requestAnimationFrame不兼容則用setTimeout
requestAnimationFrame的優點是它的革新頻次會與瀏覽器一致
setTimeout則有時刻能夠湧現喪失的狀況
內部封裝一個兩層的挪用來運用,大概是兩幀的意義
假如沒有delayed或許remove直接更新style即可
設置節點被destory時刻的style
設置刪除結果也就是挪用自定義的remove鈎子函數。假如沒有的話就挪用全局的
這些定義都是依據api瀏覽連繫源碼發明的
remove鈎子實行后才會刪除款式
snabbdom
這塊是在網上看的源碼解讀
由於diff算法應該是一個vitrual dom完成的重點了
createKeyToOldIdx 給舊節點設置key用於比對
// create => style,class,dataset,eventlistener,props,hero
// update => style,class,dataset,eventlistener,props,hero
// remove => style
// destory => eventlistener,style,hero
// pre => hero
// post => hero
這是一些鈎子函數的運用api吧
init做一些模塊的初始化 另有全局鈎子的初始化
emptyNodeAt
傳入一個節點 然後對這個節點舉行操縱提取 轉換成vnode數據對象
createRmCb
// remove攔截器 style內里說起的
// 對remove鈎子回調做減法然後才刪除節點
createElm
vnode映照實在節點
看到這裏的時刻對insertedVnodeQueue很不懂 究竟要幹嗎
然後倏忽想邃曉了。這個大概是inserted的鈎子吧- –
在每一次插進去操縱的時刻都將節點insert
api.這範例要領可以看出來是在挪用對應modules的要領
由於最先的時刻就導入進來了
插進去節點操縱的時刻都須要到場insertedVnodeQueue
子節點有子元素 也就是children的時刻遞歸挪用循環子節點天生tree
對應着一些操縱以後都要觸發鈎子函數。
之前並不清晰鈎子函數生命周期觸發道理,此次卻是見地了
invokeDestroyHook 手動觸發destroy鈎子 先觸發vnode的鈎子 在觸發全局鈎子 再遞歸觸發子節點的鈎子
removeVnodes remove操縱 由於要使得remove鈎子觸發后才刪除節點
updateChildren patchVnode 最重要的diff算法
應用前後索引的體式格局
舉行對兩樹的遍歷patch 複雜度是O(n)
由於比較都是在同層做比較對照patch
起點在patchVnode 然後patch歷程updateChildren 然後挪用updateChildrens
一個分段的偽遞歸
而當索引不見效 這個時刻則採納傳統的key-index比對
網上的一些simple vitrual dom教程
完成的是基於深度遍歷做list diff
然後獲得節點的變化
在做對應操縱 。
snabbdom的patch等等 都是基於數據對象做的。
而一些vitrual的完成是基於樹的patch
總結
virtual-dom的一個優點就是讓我們可以從冗雜無章的dom操縱中擺脫,應用js對象的情勢映照到dom,從而操縱js數據操縱dom
所謂的機能實在照樣得看你怎樣用,大片的修正dom不見得virtual dom就有多好用。
盤算也完成個simple dom 占坑~~(當然在path diff算法上能夠不存在優化了)(占坑占坑)
snabbdom也是vue運用的virtual dom 庫,emmm以後可以看看vue是怎樣連繫運用snabbdom的。
本文寫於2017年05月22日
撒花。thanks
假如有須要細緻代碼剖析的朋儕可以聯絡我獵取。