做者:Filip Rakowski翻譯:瘋狂的技術宅html
原文:https://vueschool.io/articles...前端
未經容許嚴禁轉載vue
有關即將發佈的 Vue.js 的第 3 個主要版本的信息愈來愈多。經過下面的討論,雖然還不能徹底肯定其全部內容,可是咱們能夠放心地認爲,它將是對當前版本(已經很是出色)的巨大改進。 Vue 團隊在改進框架 API 方面作得很是出色。 尤雨溪將 Vue 3 的目標描述爲:react
經過查看 RFC 並進行交談,我確信上述全部目標都會毫無問題地實現。在本文中,就其影響和可能性而言,我將討論一些對我來講最有趣的更改。webpack
做爲性能怪胎,在探究某些 API 以前我想先談一談 Vue 3 的性能。git
先從 Vue 3 的捆綁包大小開始。程序員
當前最小化並被壓縮的 Vue 運行時大小約爲 20kB(2.6.10 版爲 22.8kB)。 Vue 3捆綁包的大小估計大約會減小一半,即只有大約 10kB!github
諸如更好的模塊化之類的許多其餘優化之上,Vue 3 源代碼將是 tree-shakeable。這意味着,若是你用不到它的某些功能的話(例如 component
或 v-show
指令),則這些功能將不會包含在你的產品包中。目前不管咱們使用 Vue 核心的什麼功能,這些功能最終都會在咱們的生產代碼中使用,由於 Vue 實例做爲單個對象被導出,而且捆綁程序沒法檢測到該對象的哪些屬性在代碼中使用。web
// Vue 2.x - whole `Vue` object is bundled for production import Vue from 'vue' Vue.nextTick(() => {}) const obj = Vue.observable({})
爲了使全局 API 能夠 tree-shake,Vue 團隊決定對其中的大多數 API 經過命名導出,以便捆綁程序能夠檢測和刪除未使用的代碼:面試
// Vue 3.x - only imported properties are bundled import { nextTick, observable } from 'vue' nextTick(() => {}) const obj = observable({})
這是一個重大變化,由於如今經過命名的導出才能使用只能之前的全局 API。這個更改將會影響:
Vue.nextTick
Vue.observable
Vue.version
Vue.compile
(只限於完整版本)Vue.set
(僅在2.x兼容版本中,你會很快找到緣由)Vue.delete
(與上面相同)咱們還須要一段時間才能徹底受益於此功能,由於它須要在生態系統中採用。 Vue 團隊將發佈兼容性版本,所以咱們應該可以使用也使用舊的 API 插件,但會下降性能。
能夠 tree-shake 的 JavaScript API 不止一個。在後臺,Vue 編譯器(將 Vue 模板轉換爲渲染功能的工具)將檢測模板中使用的指令,並對其進行 tree-shake。例以下面的模板:
<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]) ]) }
每一個人都會從全局 API tree-shaking 中受益(尤爲是咱們的用戶),可是我認爲製做小型的輕量級網站並僅使用 Vue 功能子集進行交互的人(最能替代 jQuery 之類的庫)的人會對此最爲重視。
儘管捆綁包的大小可能會嚴重影響應用的加載時間,可是在下載後,它也應該可以快渲染且運行流暢。
Vue 核心團隊很是瞭解這一點,這就是爲何在運行時性能上也有很大改進的緣由。
讓咱們從最具影響力的一種系統開始,它基於 JavaScript Proxies。當前的 Vue 響應系統是基於 Object.defineProperty
的,有一些侷限性。最多見並使人沮喪的是 Vue 沒法跟蹤響應對象的屬性添加和刪除。爲此咱們須要使用 Vue.set
和 Vue.delete
來保持響應系統的正常運行。經過使用 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
代理的真正影響能夠進行更快的組件初始化和修補。 根據測試,速度大約快 2 倍!
這種改進尤其重要,由於 Vue 必須使用 getters/setters 來遞歸地遍歷全部對象及其屬性,並對其進行轉換。經過使用代理,這個過程就變得容易得多。
值得一提的是,因爲使用了 JS Proxies, Vue 3 將會放棄對 Internet Explorer(而不是Edge)的支持,可是請放心,對於但願支持 IE 的用戶來講,它會保持兼容性。
根據尤雨溪的推文,此功能不會包含在 Vue 3 中。
Vue 3 另外一個使人興奮的性能功能是對時間切片的實驗性支持,可是它不多被說起。
用一個比喻來解釋什麼是時間切片。想象有一條買冰淇淋的隊伍,它很是的長。由於那是鎮上最好的冰淇淋,人們一個接一個的去買。因爲某種緣由,沒有關於可用口味的信息。要獲得這個信息,你須要詢問直接出售冰淇淋的女士。
在這種狀況下,咱們可能最終會獲得 2 條記錄——其中一條給想要購買冰淇淋的人(說服他們耐心等待),另外一條給但願在選擇以前瞭解更多口味信息的人,咱們應該儘快得到這個信息。不幸的是,只有一位女士在賣冰淇淋,她在爲「主」線上的全部客戶提供服務以前不會回答任何問題。
對於還沒有被說服的客戶來講,這並非最好的體驗,大多數人可能會發現這不值得等待。爲了解決這個問題,女士能夠在每 2 至 3 個服務對象中回答一個問題。兩組都應該對此解決方案感到滿意。
這正是 CPU 與 Web 應用一塊兒工做的方式。咱們有一條「主」隊列(稱爲「主線程」),須要完成其全部主要任務(腳本、渲染等),而後才能響應用戶交互。對於某些頁面,這可能會致使很是糟糕的用戶體驗,具體取決於 Vue 組件加載或從新渲染所需的時間。
爲了使其更可靠,最好對此腳本進行評估並「切」成段,在每次執行後查看是否有用戶輸入要處理。這樣,不管須要進行多少次渲染或從新渲染,程序都將保持響應狀態。這就是在 Vue 3 中的工做方式。
這是尤雨溪在 Vue 3 中展現時間分片功能的方式。請注意腳本執行時間軸中的小間隙,能夠在這些間隙中處理用戶輸入。
工具與開箱即用的性能同等重要。因此咱們能夠在 Vue 3 中看到一個新的生命週期 hook ——renderTriggered。能夠用它來跟蹤和消除沒必要要的組件從新渲染,當把它與時間切片結合使用時,就成了在運行時性能優化中很是強大的武器。
const Component = { // other properties renderTriggered (event) { console.log(`Re-render of ` + this.$options.name + ` component`, event) } }
除了上面在 Vue 3 中看到的內容之外,還有不少東西,可是這些多是影響最大的。許多未說起的改進將會隱藏在 Vue 編譯器生成的代碼中,或者與實現細節和算法綁定在一塊兒
可是,有幾項改進值得一提:
另外,在將來幾天裏,你能夠期待尤雨溪撰寫的一篇深刻的文章,介紹他們專門針對 Vue 編譯器進行的性能優化。
儘管 Vue 已經成爲目前性能最好的框架之一,但咱們仍然將會在第三版中看到重大改進。特別是在捆綁包大小和運行時性能方面。還進行了無數的微優化。我認爲 Vue 3 很是適合現代移動優先和性能導向的 web。
別忘了 Vue 是惟一由社區徹底驅動的主要框架。本文中列出的全部更改都以 RFC 的形式在此處與社區一塊兒討論。你能夠幫助核心團隊,你能夠表達對有效 RFC 的意見,甚至能夠提出本身的改進建議。讓咱們一塊兒使 Vue 更好!😉
在下一篇文章中,將探討新的 Vue 3 API 將如何影響咱們編寫 web 應用的方式。咱們將研究各類 API,包括最近流行的 Composition API,並瞭解如何用它來編寫更好和更可維護的代碼。