Vue3為什么這么快
總所周知,程序員追求的就是一個字:快?。ó斎徊皇鞘裁炊甲非罂斓?,有些事情快起來是不行滴)
昨天Vue3.0正式發(fā)布了,激動的心,顫抖的手,摸了摸我的頭發(fā),嗯~還好。
據(jù)說Vue3.0相比Vue2.x在性能上提升了1.2~2倍,為啥他就這么快呢?
vue3.0做了以下事情
- diff算法優(yōu)化
- 靜態(tài)提升(hoistStatic)
- 事件偵聽器緩存(cacheHandlers)
- SSR優(yōu)化(看心情更新)
diff算法優(yōu)化
Vue2.x的diff算法
vue2.x的diff算法叫做全量比較,顧名思義,就是當數(shù)據(jù)改變的時候,會從頭到尾的進行vDom對比,即使有些內(nèi)容是永恒固定不變的。

Vue3.0的diff算法
vue3.0的diff算法有個叫靜態(tài)標記(PatchFlag)的小玩意,啥是靜態(tài)標記呢?
簡單點說,就是如果你的內(nèi)容會變,我會給你一個flag,下次數(shù)據(jù)更新的時候我直接來對比你,我就不對比那些沒有標記的了

export function render(_ctx, _cache, $props, $setup, $data, $options) {
return (_openBlock(), _createBlock("div", null, [
_createVNode("p", null, "'HelloWorld'"),
_createVNode("p", null, _toDisplayString(_ctx.msg), 1 /* TEXT */)
//上面這個1就是靜態(tài)標記
]))
}
那么肯定有人又會問了,為啥是個1呢?
TEXT = 1 // 動態(tài)文本節(jié)點 CLASS=1<<1,1 // 2//動態(tài)class STYLE=1<<2,// 4 //動態(tài)style PROPS=1<<3,// 8 //動態(tài)屬性,但不包含類名和樣式 FULLPR0PS=1<<4,// 16 //具有動態(tài)key屬性,當key改變時,需要進行完整的diff比較。 HYDRATE_ EVENTS = 1 << 5,// 32 //帶有監(jiān)聽事件的節(jié)點 STABLE FRAGMENT = 1 << 6, // 64 //一個不會改變子節(jié)點順序的fragment KEYED_ FRAGMENT = 1 << 7, // 128 //帶有key屬性的fragment 或部分子字節(jié)有key UNKEYED FRAGMENT = 1<< 8, // 256 //子節(jié)點沒有key 的fragment NEED PATCH = 1 << 9, // 512 //一個節(jié)點只會進行非props比較 DYNAMIC_SLOTS = 1 << 10 // 1024 // 動態(tài)slot HOISTED = -1 // 靜態(tài)節(jié)點 // 指示在diff算法中退出優(yōu)化模式 BALL = -2
靜態(tài)提升(hoistStatic)
Vue2.x中無論元素是否參與更新,每次都會重新創(chuàng)建然后渲染
Vue3.0中對不參與更新的元素,會做靜態(tài)提升,只會被創(chuàng)建一次,在渲染時直接復(fù)用即可
還是這段熟悉的代碼,開啟靜態(tài)提升前
export function render(_ctx, _cache, $props, $setup, $data, $options) {
return (_openBlock(), _createBlock("div", null, [
_createVNode("p", null, "'HelloWorld'"),
_createVNode("p", null, "'HelloWorld'"),
_createVNode("p", null, _toDisplayString(_ctx.msg), 1 /* TEXT */)
]))
}
開啟靜態(tài)提升后編譯結(jié)果
const _hoisted_1 = /*#__PURE__*/_createVNode("p", null, "'HelloWorld'", -1 /* HOISTED */)
const _hoisted_2 = /*#__PURE__*/_createVNode("p", null, "'HelloWorld'", -1 /* HOISTED */)
export function render(_ctx, _cache, $props, $setup, $data, $options) {
return (_openBlock(), _createBlock("div", null, [
_hoisted_1,
_hoisted_2,
_createVNode("p", null, _toDisplayString(_ctx.msg), 1 /* TEXT */)
]))
}
可以看到開啟了靜態(tài)提升后,直接將那兩個內(nèi)容為helloworld的p標簽聲明在外面了,直接就拿來用了,這么搞的話那肯定會快啊
事件偵聽器緩存
默認情況下onClick會被視為動態(tài)綁定,所以每次都會去追蹤它的變化
但是因為是同一個函數(shù),所以沒有追蹤變化,直接緩存起來復(fù)用即可
dom結(jié)構(gòu)
<div> <button @click = 'onClick'>點我</button> </div>
開啟事件偵聽器緩存之前:
export const render = /*#__PURE__*/_withId(function render(_ctx, _cache, $props, $setup, $data, $options) {
return (_openBlock(), _createBlock("div", null, [
_createVNode("button", { onClick: _ctx.onClick }, "點我", 8 /* PROPS */, ["onClick"])
// PROPS=1<<3,// 8 //動態(tài)屬性,但不包含類名和樣式
]))
})
這里有一個8,表示著這個節(jié)點有了靜態(tài)標記,有靜態(tài)標記就會進行diff算法對比差異,所以會浪費時間
開啟事件偵聽器緩存之后:
export function render(_ctx, _cache, $props, $setup, $data, $options) {
return (_openBlock(), _createBlock("div", null, [
_createVNode("button", {
onClick: _cache[1] || (_cache[1] = (...args) => (_ctx.onClick(...args)))
}, "點我")
]))
}
可以發(fā)現(xiàn),開啟事件偵聽器緩存后,沒有靜態(tài)標記了,這就快了好多嘛
到此這篇關(guān)于Vue3為什么這么快的文章就介紹到這了,更多相關(guān)Vue3 快內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue項目如何實現(xiàn)ip和localhost同時訪問
這篇文章主要介紹了vue項目如何實現(xiàn)ip和localhost同時訪問,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-10-10
vue中如何使用echarts和echarts-gl實現(xiàn)3D餅圖環(huán)形餅圖
現(xiàn)在vue是很多公司前端的主流框架,我目前所在公司接觸的項目也都是使用vue來實現(xiàn)的,很少有完全使用原生的JavaScript來寫項目的了,下面這篇文章主要給大家介紹了關(guān)于vue中如何使用echarts和echarts-gl實現(xiàn)3D餅圖環(huán)形餅圖的相關(guān)資料,需要的朋友可以參考下2023-03-03
element-ui中的clickoutside點擊空白隱藏元素
這篇文章主要為大家介紹了element-ui中的clickoutside點擊空白隱藏元素示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-03-03
vue3中實現(xiàn)使用element-plus調(diào)用message
這篇文章主要介紹了vue3中實現(xiàn)使用element-plus調(diào)用message,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-09-09
elementUI動態(tài)表單?+?el-select?按要求禁用問題
這篇文章主要介紹了elementUI動態(tài)表單?+?el-select?按要求禁用問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-10-10

