Vue3.0 性能優化及新特性

Vue3.0的六大亮點:

性能

Tree-shaking 支持

Composition API

Fragment、Teleport、Suspense

更好的 TS 支持

自定義渲染API

編譯時對VDom的性能優化

PatchFlag

首先看下面這個案例,模版中有三個P標籤,其中只有最後一個P標籤的TEXT部分是動態的

在之前的VDOM中,如果msg值發生改變,整個模版中的所有元素都需要重新渲染。但在Vue3.0中,在這個模版編譯時,編譯器會在動態標籤末尾加上 /* Text*/ PatchFlag。只能帶patchFlag 的 Node 才被認爲是動態的元素,會被追蹤屬性的修改。並且 PatchFlag 會標識動態的屬性類型有哪些,比如這裏 的TEXT 表示只有節點中的文字是動態的。

每一個Block中的節點,就算很深,也是直接跟Block一層綁定的,可以直接跳轉到動態節點而不需要逐個逐層遍歷。

既有VDOM的靈活性,又有性能保證。

hoistStatic 靜態節點提升

當使用hoistStatic時,所有 靜態的節點都被提升到render方法之外。這意味着,他們只會在應用啓動的時候被創建一次,而後隨着每次的渲染被不停的複用。

在大型應用中對於內存有很大的優化。

cacheHandler 事件監聽緩存

正常情況下,當綁定一個事件:

<div>

  <p @click="handleClick">靜態代碼</p>

</div>

模版會被編譯爲

export function render(_ctx, _cache) {

  return (_openBlock(), _createBlock("div", null, [

    _createVNode("p", { onClick: _ctx.handleClick }, "靜態代碼", 8 /* PROPS */, ["onClick"])

  ]))

}

其中事件會每次從全局上下文中獲取。而當開啓了cacheHandler之後

export function render(_ctx, _cache) {

  return (_openBlock(), _createBlock("div", null, [

    _createVNode("p", {

      onClick: _cache[1] || (_cache[1] = ($event, ...args) => (_ctx.handleClick($event, ...args)))

    }, "靜態代碼")

  ]))

}

編輯器會爲你動態創建一個內聯函數,內聯函數裏面再去飲用當前組件上最新的handler。之後編輯器會將內聯函數緩存。每次重新渲染時如果事件處理器沒有變,就會使用緩存中的事件處理而不會重新獲取事件處理器。這個節點就可以被看作是一個靜態的節點。這種優化更大的作用在於當其作用域組件時,之前每次重新渲染都會導致組件的重新渲染,在通過handler緩存之後,不會導致組件的重新渲染了。

SSR 服務端渲染

當開啓SSR了之後,如果我們模版中有一些靜態標籤,這些靜態標籤會被直接轉化成文本。

其中的動態綁定依然是一個單獨的字符串內嵌進去。這個性能肯定比React 轉成VDOM在專爲HTML快很多。

StaticNode 靜態節點

剛纔提到在SSR中靜態的節點會被轉化爲純字符串。如果在客戶端,當靜態節點嵌套足夠多的時候,VUE編譯器也會將VDOM轉化爲純字符串的HTML。即 StaticNode。

通過這些操作,我們可以看下,跟vue2比可以快一倍以上,內存佔用可以小一倍以上。

Tree Shaking

因爲ES6模塊是靜態引用的,所以我們可以在編譯時正確的判斷到底加載了哪些代碼。對代碼全局做一個分析,找到那些沒用被用到的模塊、函數、變量,並把這些去掉。

當使用一個 bundle (webpack etc.)的時候,默認會加上 TreeShaking。Vue 3.0 中沒有被用到的模塊可以不被打包到編譯後的文件中,被 TreeShake 掉。當只有一個HelloWorld的時候 Vue3打包後 13.5kb。所有的組件全部加載進來時是 22.5kb

Composition API

隨着Vue組件的增大,組件內代碼變得越來越難以理解和維護。其中的一些可以複用的代碼很難被抽離出來。同時 Vue2.0還缺少 TS支持。在Vue2中,邏輯概念(功能)被管理在組件中,但是功能和組件並不是一對一關係。一個功能可以被多個組件使用同時一個組件可以有多個功能。在Vue中,一個功能可能需要依賴多個Options(components、props、data、computed、methods及生命週期方法)。

在 Composition API中提供可 setup 方法。以一個有搜索功能和 排序功能組件爲例:

<script>

export default {

    setup() {

   

    }

}

function useSearch() {

    return {

    ...useSearch(),

    ...useSorting()

    }

}

function useSorting() {

   

}

</script>

Vue2 中的代碼複用

Mixin

在Vue2中有幾種方式可以複用代碼,其中之一就是 Mixins。

Mixins可以實現組織功能

容易發生衝突

很難說明依賴關係

代碼不容易複用

Mixin 工廠

可以方便複用

明確的依賴關係

弱命名空間

隱性的屬性添加

Scoped Slots

解決了 Mixin 的問題

增加了層級關係導致更難以理解

很多配置信息

靈活性更少

性能較差

核心 API

reactive

ref

computed

readonly

watchEffect

watch

Lifecycle Hooks

Fragments

Vue3中不在要求模版的跟節點必須是只能有一個節點。跟節點和和render函數返回的可以是純文字、數組、單個節點,如果是數組,會自動轉化爲 Fragments。

Teleport

對標 React Portal。可以做一些關於響應式的設計,如果屏幕寬度比較寬的時候,加入某些元素,屏幕變窄後移除。

Suspense

等待嵌套的異步依賴。再把一個嵌套的組件樹渲染到頁面上之前,先在內存中進行渲染,並記錄所有的存在異步依賴的組件。只有所有的異步依賴全部被resolve之後,纔會把整個書渲染到dom中。當你的組件中有一個 async的 setup函數,這個組件可以被看作是一個Async Component,只有當這個組件被Resolve之後,再把整個樹渲染出來

async setup()

Async Component

Typescript

Vue3源碼使用 TS重寫,但不意味着vue3的項目也要使用TS。但Vue3會對 TS有更好的支持

支持 TSX

支持 Class component

代碼會變大一些

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