snabbdom源碼粗讀

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上的值;

《snabbdom源碼粗讀》

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
假如有須要細緻代碼剖析的朋儕可以聯絡我獵取。

一些link

    原文作者:ZWkang
    原文地址: https://segmentfault.com/a/1190000014898185
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞