編譯器原理
我們運(yùn)行app之前執(zhí)行編譯操作
compile => render()
得到的渲染函數(shù)會(huì)在兩種情況下h執(zhí)行鞠鲜;
- 掛載時(shí)候
mount => render() => vnode(得到虛擬dom,想要變成真實(shí)dom需要執(zhí)行 ) => patch(null,n2) => 最后得到dom
在初始化的過(guò)程中渐夸,我們做了數(shù)據(jù)的響應(yīng)式和依賴收集,當(dāng)我們的數(shù)據(jù)發(fā)生變化的時(shí)候會(huì)觸發(fā)和依賴相關(guān)的函數(shù)寸莫,componentEffect,就是用來(lái)做依賴收集的函數(shù)捺萌,數(shù)據(jù)只要發(fā)生變化內(nèi)部重新執(zhí)行render函數(shù)
init => 數(shù)據(jù)響應(yīng)式+依賴收集 => componentEffect()
- Update的時(shí)候
componentEffect() => render() => vnode => patch(n1,n2) => dom
在更新的流程中档冬,我門會(huì)再次執(zhí)行render函數(shù)膘茎,生成vnode => patch(n1,n2) => 最后嘗試更新dom
編譯器執(zhí)行的時(shí)刻是什么?
在webpack環(huán)境下酷誓,vue-loader能夠.vue文件提前轉(zhuǎn)換披坏,過(guò)程中會(huì)將template預(yù)編譯,所以運(yùn)行時(shí)在項(xiàng)目打包時(shí)盐数,這種情況運(yùn)行時(shí)不需要編譯器棒拂,vue.rentime.js,這時(shí)候不允許字符串模版玫氢,即template
而vue.global.js攜帶編譯器帚屉,它會(huì)在程序運(yùn)行時(shí),去提前編譯組件模版漾峡,這時(shí)候不會(huì)預(yù)編譯攻旦;
AST(抽象語(yǔ)法數(shù))
AST和Vnode特別像,也是js對(duì)象生逸,但是最終產(chǎn)出的結(jié)果不一樣牢屋,AST最終產(chǎn)出的結(jié)果是代碼,也就是render函數(shù), 而vode是始終伴隨生命周期槽袄,最終生成dom節(jié)點(diǎn)烙无。
解析步驟:
一:parse()
=>ast
解析字符串template為抽象語(yǔ)法樹ast
步驟二:transform() 轉(zhuǎn)換
ast深加工, 最終生成的還是ast , 是對(duì)掛載的方法和屬性進(jìn)行精細(xì)的加工,解析屬性遍尺、樣式截酷、指令等
步驟三: generate() generate函數(shù)最后生成的script string 由new Function(‘function render()’) 來(lái)生成render函數(shù)生成render代碼的過(guò)程
vue3編譯器的優(yōu)化策略
1:靜態(tài)節(jié)點(diǎn)提升
靜態(tài)不變的節(jié)點(diǎn),直接把它創(chuàng)建了乾戏,放在渲染函數(shù)的外部合搅,直接使用多搀,不需要頻繁創(chuàng)建了;
2補(bǔ)丁標(biāo)記和動(dòng)態(tài)屬性記錄
添加動(dòng)態(tài)補(bǔ)丁
<p :title=“foo”>hello world</p> 對(duì)title做動(dòng)態(tài)變化的標(biāo)記灾部,等之后做diff對(duì)比的時(shí)候康铭,只做當(dāng)前的動(dòng)態(tài)值做比對(duì),減少遞歸遍歷的過(guò)程赌髓。
3緩存事件處理程序
對(duì)事件進(jìn)行緩存从藤,嘗試從緩存中獲取,render函數(shù)執(zhí)行的時(shí)候锁蠕,不會(huì)再重新創(chuàng)建夷野;
4塊block
<div id=‘a(chǎn)pp’> <div> <div></div></div> <span>{{msg}}</span></div>
對(duì)塊級(jí)中只有一個(gè)動(dòng)態(tài)的變量進(jìn)行創(chuàng)建,等執(zhí)行更新的時(shí)候荣倾,會(huì)定向的對(duì)區(qū)塊兒中的動(dòng)態(tài)元素單獨(dú)更新悯搔。
Vue3虛擬dom和patch算法
vue3對(duì)vnode結(jié)構(gòu)做了調(diào)整以適應(yīng)編譯器的優(yōu)化策略,相對(duì)應(yīng)的patch算法也會(huì)利用這些變化提高運(yùn)行速度;
vue3異步更新策略
vue3中也有一套異步更新策略