Vue 3 對 Web 應用性能的改進

作者:Filip Rakowski

翻譯:瘋狂的技術宅

原文:https://vueschool.io/articles...

未經允許嚴禁轉載

有關即將發佈的 Vue.js 的第 3 個主要版本的信息越來越多。通過下面的討論,雖然還不能完全確定其所有內容,但是我們可以放心地認爲,它將是對當前版本(已經非常出色)的巨大改進。 Vue 團隊在改進框架 API 方面做得非常出色。 尤雨溪將 Vue 3 的目標描述爲:

  • 使其更快
  • 使其更小
  • 使其更易於維護
  • 使其更容易定位到本地
  • 你的生活更輕鬆

通過查看 RFC 並進行交談,我確信上述所有目標都會毫無問題地實現。在本文中,就其影響和可能性而言,我將討論一些對我來說最有趣的更改。

性能優化

作爲性能怪胎,在探究某些 API 之前我想先談一談 Vue 3 的性能。

先從 Vue 3 的捆綁包大小開始。

當前最小化並被壓縮的 Vue 運行時大小約爲 20kB(2.6.10 版爲 22.8kB)。 Vue 3捆綁包的大小估計大約會減少一半,即只有大約 10kB!

全局 API tree-shaking

諸如更好的模塊化之類的許多其他優化之上,Vue 3 源代碼將是 tree-shakeable。這意味着,如果你用不到它的某些功能的話(例如 componentv-show 指令),則這些功能將不會包含在你的產品包中。目前無論我們使用 Vue 核心的什麼功能,這些功能最終都會在我們的生產代碼中使用,因爲 Vue 實例作爲單個對象被導出,並且捆綁程序無法檢測到該對象的哪些屬性在代碼中使用。

 // 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.setVue.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 倍!

image.png

這種改進尤爲重要,因爲 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 中展示時間分片功能的方式。請注意腳本執行時間軸中的小間隙,可以在這些間隙中處理用戶輸入。

image.png

能夠輕鬆識別爲什麼重新渲染組件的能力

工具與開箱即用的性能同等重要。所以我們可以在 Vue 3 中看到一個新的生命週期 hook ——renderTriggered。可以用它來跟蹤和消除不必要的組件重新渲染,當把它與時間切片結合使用時,就成了在運行時性能優化中非常強大的武器。

const Component = {
  // other properties
  renderTriggered (event) {
     console.log(`Re-render of ` + this.$options.name + ` component`, event)
  }
}

還有什麼

除了上面在 Vue 3 中看到的內容以外,還有很多東西,但是這些可能是影響最大的。許多未提及的改進將會隱藏在 Vue 編譯器生成的代碼中,或者與實現細節和算法綁定在一起

但是,有幾項改進值得一提:

  • 輸出代碼將更易於針對 JavaScript 編譯器進行優化
  • 輸出代碼通常會更好地進行優化
  • 由於改進了補丁算法,將避免不必要的 parent/children 重新渲染

另外,在未來幾天裏,你可以期待尤雨溪撰寫的一篇深入的文章,介紹他們專門針對 Vue 編譯器進行的性能優化。

摘要

儘管 Vue 已經成爲目前性能最好的框架之一,但我們仍然將會在第三版中看到重大改進。特別是在捆綁包大小和運行時性能方面。還進行了無數的微優化。我認爲 Vue 3 非常適合現代移動優先和性能導向的 web。

別忘了 Vue 是唯一由社區完全驅動的主要框架。本文中列出的所有更改都以 RFC 的形式在此處與社區一起討論。你可以幫助核心團隊,你可以表達對有效 RFC 的意見,甚至可以提出自己的改進建議。讓我們一起使 Vue 更好!😉

接下來是什麼

在下一篇文章中,將探討新的 Vue 3 API 將如何影響我們編寫 web 應用的方式。我們將研究各種 API,包括最近流行的 Composition API,並瞭解如何用它來編寫更好和更可維護的代碼。


本文首發微信公衆號:前端先鋒

歡迎掃描二維碼關注公衆號,每天都給你推送新鮮的前端技術文章

歡迎掃描二維碼關注公衆號,每天都給你推送新鮮的前端技術文章

歡迎繼續閱讀本專欄其它高贊文章:


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章