最近關(guān)于即將發(fā)布的 Vue.js 的第 3 個大版本的消息越來越密集。雖然本文所討論的內(nèi)容還沒有完全確定下來,但作者已經(jīng)可以肯定它將是對當(dāng)前(已經(jīng)非常出色的)版本的大幅升級铣除。
Vue 團(tuán)隊非常擅長改進(jìn)框架 API。Evan You 總結(jié)了 Vue 3 的幾大改進(jìn)目標(biāo):
- 速度更快横殴。
- 體積更小。
- 更易維護(hù)卿拴。
- 以原生為目標(biāo)更容易衫仑。
- 讓生活更輕松。
看過 RFC 和相關(guān)討論后堕花,我確信上述所有目標(biāo)都肯定能實現(xiàn)文狱。本文會帶領(lǐng)讀者瀏覽一些個人認(rèn)為最有趣的更改內(nèi)容,介紹它們的影響和潛力缘挽。
性能優(yōu)化
我非常重視性能瞄崇,所以在探索具體的 API 之前我想談一談 Vue 3 的性能『韭可講的東西是很多的苏研!幾乎每個角落都能找到明顯的改進(jìn)!
首先來看 Vue 3 的包大小腮郊。
目前摹蘑,最小化和壓縮過的 Vue 運(yùn)行時大小約為 20kB(當(dāng)前的 2.6.10 版本為 22.8kB)。Vue 3 的包估計只需一半的體積轧飞,因此只有?10kB衅鹿!
全局 API tree-shaking
Vue 3 帶來了許多諸如更好的模塊化之類的優(yōu)化,而最值得一提的是 Vue 3 源代碼將支持 tree-shaking过咬。這意味著如果你不使用它的某些功能(例如keep-alive
組件或 v-show 指令)大渤,則這些功能將不會包含在你的產(chǎn)品包中。在當(dāng)前版本中掸绞,無論我們使用 Vue 核心中的哪些功能泵三,所有未使用的功能最終都會進(jìn)入我們的生產(chǎn)代碼,因為 Vue 實例是作為單個對象導(dǎo)出的,并且打包器無法檢測出代碼中使用了對象的哪些屬性切黔。
復(fù)制代碼
// Vue 2.x - whole `Vue` object is bundled for productionimport Vue from 'vue' Vue.nextTick(() => {})const obj = Vue.observable({})
為了使全局 API 支持 tree-shaking砸脊,Vue 團(tuán)隊決定通過命名導(dǎo)出導(dǎo)入其中的大多數(shù) API具篇,以便打包器可以檢測出未使用的代碼并刪除它們:
復(fù)制代碼
// Vue 3.x - only imported properties are bundledimport { nextTick, observable } from 'vue' nextTick(() => {})const obj = observable({})
這是一個重大變化纬霞,因為以前的全局 API 現(xiàn)在只能通過命名的導(dǎo)出才能使用。這一更改會影響:
- Vue.nextTick
- Vue.observable
- Vue.version
- Vue.compile(僅限完整構(gòu)建)
- Vue.set(僅在 2.x 兼容版本中驱显,很快你就知道為什么了)
- Vue.delete(與上同)
我們需要一段時間才能完全享受到這一功能的好處诗芜,因為它需要在一個在生態(tài)系統(tǒng)中的普及過程。Vue 團(tuán)隊將發(fā)布兼容版本埃疫,因此我們也應(yīng)該能用那些使用了舊 API 的插件伏恐,代價就是影響性能。
支持 tree-shaking 的 JavaScript API 不止一個栓霜。在后臺翠桦,Vue 編譯器(將 Vue 模板轉(zhuǎn)換為渲染函數(shù)的工具)將檢測模板中使用的指令,并對其進(jìn)行 tree-shaking胳蛮。以下面的模板為例:
復(fù)制代碼
<transition> <div v-show="ok">hello</div></transition>
在被 Vue 編譯器處理后销凑,代碼差不多會變成下面這個樣子:
復(fù)制代碼
import { h, Transition, applyDirectives, vShow } from 'vue' export function render() { return h(Transition, [ applyDirectives(h('div', 'hello'), this, [vShow, this.ok]) ])}
所有人都會從全局 API tree-shaking 中受益(尤其是我們的用戶),但我認(rèn)為最看重這一功能的是那些制作小型仅炊,輕量級網(wǎng)站并只使用 Vue 的一部分功能來開發(fā)交互的開發(fā)者斗幼,他們主要用 Vue 來替代 jQuery 之類的庫。
基于代理的響應(yīng)性
包的大小可能會嚴(yán)重影響你的應(yīng)用加載時間抚垄,但是包被完整下載后蜕窿,它也應(yīng)該快速渲染并流暢運(yùn)行。
Vue 核心團(tuán)隊非常了解這一點(diǎn)呆馁,因此我們在運(yùn)行時性能上也有很大的改進(jìn)桐经。
首先來看影響最大的部分——一種基于 JavaScript 代理的新的響應(yīng)系統(tǒng)。當(dāng)前版本的 Vue 響應(yīng)系統(tǒng)是基于 Object.defineProperty 的浙滤,其存在一些局限次询。最常見且令人沮喪的一個限制是 Vue 無法跟蹤響應(yīng)對象的屬性添加 / 刪除。為此我們需要使用 Vue.set 和 Vue.delete 來保證響應(yīng)系統(tǒng)的運(yùn)行符合預(yù)期瓷叫。有了 JS 代理后屯吊,我們終于可以擺脫這種丑陋的解決方案了。
復(fù)制代碼
// Adding a new property to reacitve object in Vue 2.xVue.set(this.myObject, key, value)// Adding a new property to reactive object in Vue 3this.myObject[key] = value
代理的好處可以從更快的組件初始化和修補(bǔ)中看出來摹菠。根據(jù)測試盒卸,現(xiàn)在的速度是之前的 2 倍!
這種改進(jìn)尤為重要次氨,因為 Vue 必須使用 getters/setters 來遞歸地遍歷所有對象及其屬性蔽介,并轉(zhuǎn)換它們。使用代理后,這一過程就變得容易很多虹蓄。
值得一提的是犀呼,使用 JS 代理后,Vue 3 會放棄對 Internet Explorer 的支持(不包括 Edge)薇组,但請放心外臂,對于希望支持 IE 的用戶來說會有一個兼容版本可用。
時間分片
根據(jù) Evan You 的推文律胀,此功能不會包含在 Vue 3 中宋光。
Vue 3 之后的版本還會帶來另一個非常激動人心,但很少被提到的功能炭菌,那就是對時間分片的試驗性支持罪佳。
打個比方來解釋什么是時間分片。想象一家甜品店前排了長長的隊伍黑低,因為店里在賣鎮(zhèn)上最好的冰淇淋赘艳。一個人買到冰淇淋后就輪到下一個,以此類推克握。由于某種原因蕾管,大家不知道有哪些口味可供選擇。要獲取這一信息玛荞,你需要直接詢問出售冰淇淋的柜臺售貨員娇掏。
在這種情況下,我們最后可能會看到兩條隊伍——其中一條是想要買冰淇淋的顧客(耐心等待)勋眯,另一條則是那些希望在決定是否購買冰淇淋之前了解更多口味信息的顧客婴梧。后者希望盡快獲得這一信息。不幸的是客蹋,只有一位女士在賣冰淇淋塞蹭,她在為“主”隊伍中的所有顧客提供完服務(wù)之前不會回答任何問題。
對于還沒下決定的顧客來說讶坯,這并不是最好的體驗番电,他們中的大多數(shù)人可能會覺得等那么久并不值當(dāng)。為了解決這個問題辆琅,賣冰淇淋的女士可以在每服務(wù) 2 至 3 位顧客后回答一個關(guān)于口味的問題漱办。這樣一來兩條隊伍中的顧客都應(yīng)該會滿意這個解決方案。
這正是 CPU 運(yùn)行 Web 應(yīng)用程序的工作機(jī)制婉烟。我們有一條“主”隊列(稱為“主線程”)娩井,需要完成應(yīng)用的所有主要任務(wù)(腳本、渲染等)似袁,然后才能響應(yīng)用戶交互洞辣。對于某些頁面來說咐刨,這可能會導(dǎo)致非常糟糕的用戶體驗,具體取決于 Vue 組件加載或重新渲染所需的時間扬霜。
為了讓它更加可靠定鸟,最好將這一腳本運(yùn)算過程“切成”小段,并在每小段執(zhí)行后查看是否有用戶輸入要處理著瓶。這樣联予,無論需要多少次渲染或重新渲染,應(yīng)用程序都將保持響應(yīng)狀態(tài)蟹但。這就是在 Vue 3 未來版本中的工作機(jī)制躯泰。
Evan 用下面的圖片展示了 Vue 3 中時間分片功能的例子谭羔。請注意腳本執(zhí)行時間軸中的小間隙华糖,這些間隙是用來處理用戶輸入的。
輕松識別為什么組件會重新渲染
工具與開箱即用的性能同等重要瘟裸。據(jù)此客叉,我們會在 Vue 3 中看到一個新的生命周期 hook——renderTriggered。我們可以使用它來跟蹤和消除不必要的組件重新渲染话告,將其與時間分片配合使用兼搏,就成為了優(yōu)化運(yùn)行時性能的非常強(qiáng)大的武器。
復(fù)制代碼
const Component = { // other properties renderTriggered (event) { console.log(`Re-render of ` + this.$options.name + ` component`, event) }}
還有什么
除了上面提到的這些內(nèi)容沙郭,Vue 3 加入的改進(jìn)還有很多很多佛呻,但本文提到的這些更改可能是影響最大的。大多數(shù)未提及的改進(jìn)將隱藏在 Vue 編譯器生成的代碼中病线,或者融入實現(xiàn)細(xì)節(jié)和算法中吓著。
還有幾項改進(jìn)值得一提:
- 輸出代碼將更容易針對 JavaScript 編譯器優(yōu)化。
- 輸出代碼通常會更好地優(yōu)化送挑。
- 由于改進(jìn)了補(bǔ)丁算法绑莺,將避免不必要的父級 / 子級重新渲染。
總結(jié)
盡管 Vue 已經(jīng)稱得上是目前性能最好的框架之一惕耕,但我們還是會在第三版中看到許多重大改進(jìn)纺裁,特別是在包大小和運(yùn)行時性能等方面。此外 Vue 3 還帶來了無數(shù)細(xì)小的優(yōu)化司澎。我認(rèn)為 Vue 3 非常適合現(xiàn)代移動優(yōu)先和性能導(dǎo)向的 Web 開發(fā)工作欺缘。
別忘了 Vue 是唯一由社區(qū)完全驅(qū)動的主流框架。本文列出的所有更改(和其他更多更改)都以 RFC 的形式與社區(qū)一起討論過了挤安。你可以幫助核心團(tuán)隊谚殊,表達(dá)你對活躍 RFC 的意見,甚至可以提出自己的改進(jìn)建議漱受。
讓我們一起使 Vue 變得更好??
下一步計劃
在下一篇文章中络凿,我們將探討新的 Vue 3 API 將如何影響我們編寫 Web 應(yīng)用程序的方式骡送。我們將研究各種 API,包括最近流行的 Composition API絮记,并了解如何使用它來編寫更好和更易維護(hù)的代碼摔踱。
作者介紹:
Filip Rakowski 是 Web 開發(fā)人員,對最新的 Web 技術(shù)充滿熱情怨愤,并特別喜歡 Vue 和漸進(jìn)式 Web 應(yīng)用派敷。他的日常工作是開發(fā)開源產(chǎn)品,開發(fā)程序員接口以及與社區(qū)互動撰洗。他是 Vue Storefront 的聯(lián)合創(chuàng)始人篮愉、StorefrontUI 的作者、Vue.js 官方社區(qū)合作伙伴和 VuePress 核心團(tuán)隊成員差导。
原文鏈接:
https://vueschool.io/articles/vuejs-tutorials/faster-web-applications-with-vue-3/