一、性能比2.x快1.2~2倍
diff演算法的優化
在vue2中,虛擬dom是全量比較的,
在vue3中,增加了靜態標記PatchFlag,在創建vnode的時候,會根據vnode的內容是否可以變化,為其添加靜態標記PatchFlag,diff的時候,只會比較有PatchFlag的節點,PatchFlag是有型別的,比如一個可變化文本節點,會將其添加PatchFlag列舉值為TEXT的靜態標記,這樣在diff的時候,只需比對文本內容,需要比對的內容更少了,PatchFlag還有動態class、動態style、動態屬性、動態key屬性等列舉值,
render階段的靜態提升(render階段指生成虛擬dom樹的階段)
在vue2中,一旦檢查到資料變化,就會re-render組件,所有的vnode都會重新創建一遍,形成新的vdom樹,
在vue3中,對于不參與更新的vnode,會做靜態提升,只會被創建一次,在re-render時直接復用,
靜態提升可以理解為第一次render不參與更新的vnode節點的時候,保存它們的參考,re-render新vdom樹時,直接拿它們的參考過來即可,無需重新創建,
事件偵聽快取
在vue2中,我們寫的@click="onClick"也是被當作動態屬性,diff的時候也要對比,但我們知道它不會變化,比如變成@click=“onClick2”,系結別的值,
在vue3中,如果事件是不會變化的,會將onClick快取起來(跟靜態提升達到的效果類似),該節點也不會被標記上PatchFlag(也就是無需更新的節點),這樣在render和diff兩個階段,事件偵聽屬性都節約了不必要的性能消耗,
我曾經維護過一個擁有很龐大dom樹的頁面,由于節點非常多,無需參與更新的節點也很多,使用vue2的情況下,在render和diff兩個階段,消費了很多性能,如果當時有vue3的話,我想性能會被優化很多,
減少創建組件實體的開銷
vue2.x每創建一個實體,在this上要暴露data、props、computed這些,都是靠Object.defineProperty去定義的,這部分操作還是挺費時的,
vue3.0中基于Proxy,減少了創建組件實體的性能開銷,
二、按需編譯,體積比Vue2.x更小(Tree shaking)
在vue3中,可以如下面這樣參考vue的功能函式,如果你的專案沒有用到watch,那編譯時就會把tree shaking掉,
import { computed, watch, nextTick } from “vue”;
利用的就是 ES6 模塊系統import/export,
三、Compostion API: 組合API/注入API
這里要說到代碼的組織方式,傳統的網頁是html/css/javascript(結構/樣式/邏輯)分離,vue/react通過組件化的方式,將聯系緊密的結構/樣式/邏輯放在一起,有利于代碼的維護,
compostion api更進一步,著力于JavaScript(邏輯)部分,將邏輯相關的代碼放在一起,近而有利于代碼的維護,
在vue2的組件內,使用的是Option API風格(data/methods/mounted)來組織的代碼,這樣會讓邏輯分散,舉個例子就是我們完成一個計數器功能,要在data里宣告變數,在methods定義回應函式,在mounted里初始化變數,如果在一個功能比較多、代碼量比較大的組件里,你要維護這樣一個功能,就需要在data/methods/mounted反復的切換到對應位置,然后進行代碼的更改,
在vue3中,使用setup函式,如下所示跟count相關的邏輯,都放到counter.js檔案里,跟todo相關的邏輯放到todos.js里,
import useCounter from ‘./counter’
import useTodo from ‘./todos’
setup(){
let { val, todos, addTodo } = useTodo()
let {count,add} = useCounter()
return {
val, todos, addTodo,
count,add,
}
}
在我看來這就是Compostion API最大的特點,以功能為單位的代碼組織方式,同時它可以讓代碼更易重用,
說到重用,Compostion API的方式也比mixin的方式好很多,你可以清楚的看到組件使用的資料和方法來自哪個模塊,而mixin進組件的功能,常常會讓我們困惑此功能來自哪個mixin,
四、更好的TS支持
vue2不適合使用ts,原因在于vue2的Option API風格,options是個簡單物件,而ts是一種型別系統、面向物件的語法,兩者有點不匹配,
在vue2結合ts的具體實踐中,要用 vue-class-component 強化 vue 組件,讓 Script 支持 TypeScript 裝飾器,用 vue-property-decorator 來增加更多結合 Vue 特性的裝飾器,最終搞的ts的組件寫法和js的組件寫法差別挺大,
在vue3中,量身打造了defineComponent函式,使組件在ts下,更好的利用引數型別推斷 ,Composition API 代碼風格中,比較有代表性的api就是 ref 和 reactive,也很好的支持了型別宣告,
import { defineComponent, ref } from ‘vue’
const Component = defineComponent({
props: {
success: { type: String },
student: {
type: Object as PropType,
required: true
}
},
setup() {
const year = ref(2020)
const month = ref<string | number>(‘9’)
month.value = 9 // OK
const result = year.value.split(’’) // => Property ‘split’ does not exist on type ‘number’
}
五、自定義渲染API(Custom Renderer API)
vue2.x架構問題
vue2.x最開始支持運行在瀏覽器中,渲染到瀏覽器的dom上,隨著vue的流行,出現了weex和myvue,
weex:移動端跨平臺方案,需要渲染到移動設備,weex被寫在vue原專案里,缺點是這使vue原專案更大了,也不是通用解決方案,
myvue:小程式上使用,需要渲染到小程式框架上,myvue是單獨fork一份源代碼進行更改,缺點也非常明顯,myvue中vue的版本跟官方版本從fork的那一刻開始,就要開始不一致了,
vue2.x專案架構對于這種渲染到不同平臺不太友好,vue3.0推出了自定義渲染API解決了該問題,
下面我們先看vue2和vue3的入口寫法有所不同:
// vue2
import Vue from ‘vue’
import App from ‘./App.vue’
new Vue({ => h(App)}).$mount(’#app’)
// vue3
const { createApp } from ‘vue’
import App from “./src/App”
createApp(App).mount((’#app’)
vue官方實作的 createApp 會給我們的 template 映射生成 html 代碼,但是要是你不想渲染生成到 html ,而是要渲染生成到 canvas 之類的不是html的代碼的時候,那就需要用到 Custom Renderer API 來定義自己的 render 渲染生成函式了,
// 你自己實作一個createApp,比如是渲染到canvas的,
import { createApp } from “./runtime-render”;
import App from “./src/App”; // 根組件
createApp(App).mount(’#app’);
有了Custom Renderer API,如weex和myvue這類方案的問題就得到了完美解決,只需重寫createApp即可,
六、更先進的組件
Fragment組件
// vue2是不允許這樣寫的,組件必須有一個跟節點,現在可以這樣寫,vue將為我們創建一個虛擬的Fragment節點,
這樣寫有何好處呢?一是如果根節點不是必要的,無需創建了,減少了節點數,二是Fragment節點是虛擬的,不會DOM樹中呈現,
Suspense組件
<template #fallback>
Loading…
在Suspended-component完全渲染之前,備用內容會被顯示出來,如果是異步組件,Suspense可以等待組件被下載,或者在設定函式中執行一些異步操作,
七、更快的開發體驗(vite開發構建工具)
在使用webpack作為開發構建工具時,npm run dev都要等一會,專案越大等的時間越長,熱多載頁有幾秒的延遲,但是如果用vite來做vue3的開發構建工具,npm run dev 秒開,熱多載也很快,這種開發體驗真是很爽,拒絕等待,
vite的原理還是用了瀏覽器支持import關鍵字了,啟動專案不用webpack構建工具先構建了,瀏覽器直接請求路由對應的代碼檔案,代理服務器針對單個檔案進行編譯并回傳,如果請求的檔案里還import了其他檔案,同理瀏覽器繼續發請求,代理服務器回傳,就這樣實作了npm run dev時無需編譯,實時請求實時編譯,
總結:
其他的,資料監聽方式變成了Proxy,消除了Object.defineProperty現有的限制(例如無法檢測新的屬性添加),并提供更好的性能,
vue3解決了vue2的一些問題,大型應用的性能問題、ts支持不友好問題,自定義渲染API解決體系架構存在的問題,如果在vue3的基礎上實作weex框架會好很多,也做出了很多優化,Compostion API讓代碼的組織形式更好,vite開發構建工具讓開發體驗更好,Tree shaking讓包更小、性能更優,
總的來說vue3還是非常棒的,帶來了很多非常好的新特性,

轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/293626.html
標籤:其他
上一篇:計算一個元素在陣列中出現的次數
