Vue 3.0 性能提高主要是經過哪幾個方面體現的?

前言

若是是 Vue 的忠實er,會知道 Vue.js 2.x 已是足夠優秀的前端框架,而且性能也不錯,可是在升級的 Vue 3.0 版本中,讓這個性能更上一層樓,那 Vue3.0 性能又有了哪些方面的突破了?前端

Vue 3 與 Vue 2 相比:vue

  • 在 bundle 包大小方面(tree-shaking 減小了 41% 的體積)node

  • 初始渲染速度方面(快了 55%)git

  • 更新速度方面(快了 133%)github

  • 內存佔用方面(減小了 54%)web

這篇文章你將瞭解 Vue 3.0 性能優化的三個方法:算法

  • 源碼體積優化緩存

  • 數據劫持優化性能優化

  • 編譯優化前端框架

1. 源碼體積優化

tree-shaking,它的原理很簡單,tree-shaking 依賴 ES2015 模塊語法的靜態結構(即 import 和 export),經過編譯階段的靜態分析,找到沒有引入的模塊並打上標記。利用 tree-shaking 技術,若是你在項目中沒有引入無關的組件,那麼它們對應的代碼就不會打包,這樣也就間接達到了減小項目引入的 Vue.js 包體積的目的。

Vue3.0 中最直接使用 tree-shaking 技術的一個例子,在 createApp 時會經過 ensureRenderer 建立渲染器對象,可是這裏並非直接建立渲染器對象,而是延時建立渲染器,目的是當用戶只依賴響應式包的時候,能夠經過 tree-shaking 移除核心渲染邏輯相關的代碼。

2. 數據劫持優化

咱們先來回憶一下,在 Vue 3.0 以前的數據劫持,Vue.js 1.x 和 Vue.js 2.x 內部都是經過 Object.defineProperty 這個 API 去劫持數據的 getter 和 setter,具體是這樣的:

Object.defineProperty(data, 'x',{
  get(){
    // 收集
  },
  set(){
    // 更新
  }
})
複製代碼

核心就是 Object.defineProperty,其實 Vue.js 1.x 和 Vue.js 2.x 不支持 IE 8 及如下也是由於 Object.defineProperty 不支持。數據劫持是 Vue.js 區別於 React 的一大特點,Vue 框架中 DOM 是數據的一種映射,數據發生變化後能夠自動更新 DOM,用戶只須要專一於數據的修改,沒有其他的心智負擔。

在 Vue.js 3.0 使用了 Proxy API 作數據劫持,它是這樣的:

observed = new Proxy(data, {
  get() {
    // 收集
  },
  set() {
    // 更新
  }
});
複製代碼

爲何替換 Object.defineProperty 到 Proxy

Object.defineProperty 和 Proxy 均可以進行數據的劫持,那爲何還要將 Object.defineProperty 替換爲 Proxy 了。緣由有兩個:

Proxy 是如何解決 Object.defineProperty API 的缺陷

3. 編譯優化

經過數據劫持和依賴收集,Vue.js 2.x 的數據更新並觸發從新渲染的粒度是組件級的:

<template>
  <div id="content">
    <p class="text">1</p>
    <p class="text">2</p>
    <p class="text">3</p>
    <p class="text">{{message}}</p>
    <p class="text">4</p>
    <p class="text">5</p>
    <p class="text">6</p>
  </div>
</template>
複製代碼

雖然這段代碼中只有一個動態節點,但在若是 message 發生改變,單個組件內部依然須要遍歷該組件的整個 vnode 樹,因此這裏有不少 diff 和遍歷其實都是不須要的,這就會致使 vnode 的性能跟模版大小正相關,跟動態節點的數量無關,當一些組件的整個模版內只有少許動態節點時,這些遍歷都是性能的浪費。

Vue.js 3.0 作到了,它經過編譯階段對靜態模板的分析,編譯生成了 Block tree。Block tree 是一個將模版基於動態節點指令切割的嵌套區塊,每一個區塊內部的節點結構是固定的,並且每一個區塊只須要以一個 Array 來追蹤自身包含的動態節點。

藉助 Block tree,Vue.js 將 vnode 更新性能由與模版總體大小相關提高爲與動態內容的數量相關,這是一個很是大的性能突破。

除此以外,Vue.js 3.0 在編譯階段還包含了對 Slot 的編譯優化、事件偵聽函數的緩存優化,而且在運行時重寫了 diff 算法。

參考

相關文章
相關標籤/搜索