我們傾向于聽到越來越多有關(guān)即將發(fā)布的Vue.js的第3個主要版本的信息俱萍。通過下面的討論醒第,雖然還不能確定所有內(nèi)容,但是我們可以放心地認(rèn)為,它將是對當(dāng)前版本(已經(jīng)非常出色)的巨大改進(jìn)舞肆。Vue團(tuán)隊在改進(jìn)框架API方面做得非常出色。Evan You將Vue 3的目標(biāo)描述為:
- 讓它更快
- 讓它更小
- 使它更易于維護(hù)
- 使其更容易瞄準(zhǔn)本土
- 讓您的生活更輕松
通過查看RFC并進(jìn)行交談博杖,我確信上述所有目標(biāo)都可以毫無問題地實現(xiàn)椿胯。在本文中,我想引導(dǎo)您完成一些對我來說最有趣的更改剃根,這些更改就其影響和可能性而言哩盲。
性能優(yōu)化
在探討某些API之前,作為性能極客狈醉,我想談一談Vue 3的性能廉油。還有很多要討論的問題!我們幾乎可以在每個表面上找到明顯的改進(jìn)苗傅!
讓我們從Vue 3的捆綁包大小開始抒线。
當(dāng)前最小化和壓縮的Vue運行時權(quán)重約為20kB(當(dāng)前2.6.10版本為22.8kB)。Vue 3捆綁包估計重約一半渣慕,因此只有?10kB嘶炭!
全球API搖樹
諸如更好的模塊化之類的許多其他優(yōu)化之上抱慌,Vue 3源代碼將是可tree-shakeable。這意味著眨猎,如果您不使用其某些功能(例如<keep-alive>
組件或v-show
指令)抑进,它們將不會包含在您的產(chǎn)品包中。當(dāng)前睡陪,無論我們從Vue核心使用什么功能寺渗,它們最終都會出現(xiàn)在生產(chǎn)代碼中,因為Vue實例作為單個對象導(dǎo)出宝穗,并且捆綁程序無法檢測到該對象的哪些屬性在代碼中使用。
// Vue 2.x - whole `Vue` object is bundled for production
import Vue from 'vue'
Vue.nextTick(() => {})
const obj = Vue.observable({})
為了使全局API可以搖樹码秉,Vue團(tuán)隊決定通過命名導(dǎo)出導(dǎo)入其中的大多數(shù)逮矛,以便捆綁程序可以檢測和刪除未使用的代碼:
// Vue 3.x - only imported properties are bundled
import { nextTick, observable } from 'vue'
nextTick(() => {})
const obj = observable({})
這是一個重大變化,因為以前的全局API現(xiàn)在僅可通過命名的導(dǎo)出使用转砖。此更改影響:
Vue.nextTick
Vue.observable
Vue.version
-
Vue.compile
(僅完整版本) -
Vue.set
(僅在2.x兼容版本中须鼎,您很快會找到原因) -
Vue.delete
(同上)
我們需要一段時間才能完全受益于此功能,因為它需要在生態(tài)系統(tǒng)中采用府蔗。Vue團(tuán)隊將發(fā)布兼容性版本晋控,因此我們應(yīng)該能夠使用也使用舊API的插件,但會降低性能姓赤。
可以搖樹的JavaScript API不止一個赡译。在后臺,Vue編譯器(將Vue模板轉(zhuǎn)換為渲染功能的工具)將檢測模板中使用的指令不铆,并對其進(jìn)行樹狀搖動蝌焚。例如下面的模板:
<transition>
<div v-show="ok">hello</div>
</transition>
在被Vue編譯器處理后,看起來或多或少是這樣的:
import { h, Transition, applyDirectives, vShow } from 'vue'
export function render() {
return h(Transition, [
applyDirectives(h('div', 'hello'), this, [vShow, this.ok])
])
}
每個人都會從全局APItree-shaking
中受益(尤其是我們的用戶)誓斥,但是我認(rèn)為制作小型只洒,輕量級網(wǎng)站并僅使用Vue功能子集進(jìn)行交互的人(最能替代jQuery之類的庫)的人會最看重它。
基于代理的反應(yīng)性
捆綁包的大小會顯著影響您的應(yīng)用加載時間劳坑,但是下載后毕谴,捆綁包的大小也應(yīng)能夠快速呈現(xiàn)且運行流暢。
Vue核心團(tuán)隊非常了解這一點距芬,這就是為什么我們在運行時性能上也有很大改進(jìn)的原因涝开。
讓我們從基于JavaScript Proxies的最具影響力的新反應(yīng)系統(tǒng)之一開始。當(dāng)前的Vue反應(yīng)系統(tǒng)是基于的Object.defineProperty
框仔,它有一些局限性忠寻。最常見和令人沮喪的一個事實是Vue無法跟蹤反應(yīng)對象的屬性添加/刪除。為此存和,我們需要使用Vue.set
并Vue.delete
保持反應(yīng)系統(tǒng)正常運行奕剃。有了JS Proxies衷旅,我們終于可以擺脫這種丑陋的解決方法。
// Adding a new property to reacitve object in Vue 2.x
Vue.set(this.myObject, key, value)
// Adding a new property to reactive object in Vue 3
this.myObject[key] = value
代理的真正影響可以從更快的組件初始化和修補(bǔ)中看出纵朋。根據(jù)測試柿顶,速度大約快2倍!
由于以下事實操软,這種改進(jìn)的原因尤為重要嘁锯,那就是Vue必須使用吸氣劑/設(shè)置劑來遞歸地遍歷所有對象及其屬性并對其進(jìn)行轉(zhuǎn)換。使用代理聂薪,此過程變得容易得多家乘。
重要的是要提到,通過使用JS Proxies Vue 3藏澳,將放棄對Internet Explorer(不是Edge)的支持仁锯,但是請不要擔(dān)心-對于希望支持IE的用戶,將有一個兼容版本翔悠。
時間分片
根據(jù)Evan You的推文更新此功能不會包含在Vue 3中业崖。
Vue 3的另一個真正令人興奮但很少提及的性能功能是對時間切片的實驗支持。
我將用一個隱喻來解釋什么是時間切片蓄愁。我想讓你想象一條冰淇淋生產(chǎn)線双炕。很長的一個,因為那是鎮(zhèn)上最好的冰淇淋撮抓。提供一個人之后妇斤,就會出現(xiàn)另一個人,依次類推丹拯。等等趟济。由于某種原因,沒有關(guān)于可用口味的信息咽笼。要獲取此信息顷编,您需要詢問直接出售冰淇淋的女士。
在這種情況下剑刑,我們可能最終會得到2條記錄-其中一條給說服他們想要購買冰淇淋的人(耐心等待)媳纬,另一條給希望在選擇風(fēng)味之前了解更多口味信息的人。不是施掏。最新的應(yīng)該盡快獲得此信息钮惠。不幸的是,只有一位女士在賣冰淇淋七芭,在為“主”線上的所有客戶服務(wù)之前素挽,她不會回答任何問題。
對于尚未被說服的客戶來說狸驳,這并不是最好的體驗预明,他們中的大多數(shù)人可能會發(fā)現(xiàn)不值得等待缩赛。為了解決這個問題,女士可以在每2至3個服務(wù)對象中回答一個問題撰糠。兩組都應(yīng)該對此解決方案感到滿意酥馍。
這正是CPU與Web應(yīng)用程序一起工作的方式。我們有一條“主”行(稱為“主線程”)阅酪,需要完成其所有主要任務(wù)(腳本旨袒,渲染等),然后才能響應(yīng)用戶交互术辐。對于某些頁面砚尽,這可能會導(dǎo)致非常糟糕的用戶體驗,具體取決于Vue組件加載或重新渲染所需的時間辉词。
為了使其更可靠必孤,最好將此腳本評估“切割”成碎片,然后查看每個腳本評估之后是否有要處理的用戶輸入较屿。這樣隧魄,無論需要進(jìn)行多少次渲染或重新渲染卓练,應(yīng)用程序都將保持響應(yīng)狀態(tài)隘蝎。這就是在Vue 3中的工作方式。
這是Evan在Vue 3中展示時間分片功能的方式襟企。請注意腳本執(zhí)行時間軸中的小間隙嘱么,這些間隙旨在處理用戶輸入。
能夠輕松識別為什么重新渲染組件
工具與開箱即用的性能同等重要顽悼。據(jù)此曼振,我們可以在Vue 3中看到一個新的生命周期掛鉤-renderTriggered。我們可以使用它來跟蹤和消除不必要的組件重新渲染蔚龙,當(dāng)將其與時間切片結(jié)合使用時冰评,這是在運行時性能優(yōu)化中非常強(qiáng)大的武器。
const Component = {
// other properties
renderTriggered (event) {
console.log(`Re-render of ` + this.$options.name + ` component`, event)
}
}
還有什么
除了上面在Vue 3中看到的內(nèi)容以外木羹,還有很多內(nèi)容甲雅,但是這些可能是影響最大的更改。大多數(shù)未提及的改進(jìn)將隱藏在Vue編譯器生成的代碼中坑填,或者與實現(xiàn)細(xì)節(jié)和算法綁定在一起
但是抛人,有幾項改進(jìn)值得一提:
- 輸出代碼將更易于針對JavaScript編譯器進(jìn)行優(yōu)化
- 輸出代碼通常會更好地進(jìn)行優(yōu)化
- 由于改進(jìn)了補(bǔ)丁算法,將避免不必要的父母/孩子重新渲染
另外脐瑰,在接下來的幾天里妖枚,您可以期待Evan You撰寫的一篇深入的文章,介紹其專門針對Vue編譯器進(jìn)行的性能優(yōu)化(發(fā)布后苍在,我將使用鏈接對其進(jìn)行更新)绝页。
概括
即使Vue已經(jīng)確立為目前性能最好的框架之一荠商,但我們?nèi)詫⒃诘谌嬷锌吹街卮蟾倪M(jìn)。特別是在捆綁包大小和運行時性能方面抒寂。還進(jìn)行了無數(shù)的微優(yōu)化结啼。我認(rèn)為Vue 3非常適合現(xiàn)代移動優(yōu)先和性能導(dǎo)向的網(wǎng)絡(luò)。