Vue3為什麼這麼快
總所周知,程式設計師追求的就是一個字:快!(當然不是什麼都追求快的,有些事情快起來是不行滴)
昨天Vue3.0正式釋出了,激動的心,顫抖的手,摸了摸我的頭髮,嗯~還好。
據說Vue3.0相比Vue2.x在效能上提升了1.2~2倍,為啥他就這麼快呢?
vue3.0做了以下事情
- diff演算法優化
- 靜態提升(hoistStatic)
- 事件偵聽器快取(cacheHandlers)
- SSR優化(看心情更新)
diff演算法優化
Vue2.x的diff演算法
vue2.x的diff演算法叫做全量比較,顧名思義,就是當資料改變的時候,會從頭到尾的進行vDom對比,即使有些內容是永恆固定不變的。
Vue3.0的diff演算法
vue3.0的diff演算法有個叫靜態標記(PatchFlag)的小玩意,啥是靜態標記呢?
簡單點說,就是如果你的內容會變,我會給你一個flag,下次資料更新的時候我直接來對比你,我就不對比那些沒有標記的了
export function render(_ctx,_cache,$props,$setup,$data,$options) { return (_openBlock(),_createBlock("div",null,[ _createVNode("p","'HelloWorld'"),_createVNode("p",_toDisplayString(_ctx.msg),1 /* TEXT */) //上面這個1就是靜態標記 ])) }
那麼肯定有人又會問了,為啥是個1呢?
TEXT = 1 // 動態文字節點 CLASS=1<<1,1 // 2//動態class STYLE=1<<2,// 4 //動態style PROPS=1<<3,// 8 //動態屬性,但不包含類名和樣式 FULLPR0PS=1<<4,// 16 //具有動態key屬性,當key改變時,需要進行完整的diff比較。 HYDRATE_ EVENTS = 1 << 5,// 32 //帶有監聽事件的節點 STABLE FRAGMENT = 1 << 6,// 64 //一個不會改變子節點順序的fragment KEYED_ FRAGMENT = 1 << 7,// 128 //帶有key屬性的fragment 或部分子位元組有key UNKEYED FRAGMENT = 1<< 8,// 256 //子節點沒有key 的fragment NEED PATCH = 1 << 9,// 512 //一個節點只會進行非props比較 DYNAMIC_SLOTS = 1 << 10 // 1024 // 動態slot HOISTED = -1 // 靜態節點 // 指示在diff演算法中退出優化模式 BALL = -2
靜態提升(hoistStatic)
Vue2.x中無論元素是否參與更新,每次都會重新建立然後渲染
Vue3.0中對不參與更新的元素,會做靜態提升,只會被建立一次,在渲染時直接複用即可
還是這段熟悉的程式碼,開啟靜態提升前
export function render(_ctx,1 /* TEXT */) ])) }
開啟靜態提升後編譯結果
const _hoisted_1 = /*#__PURE__*/_createVNode("p","'HelloWorld'",-1 /* HOISTED */) const _hoisted_2 = /*#__PURE__*/_createVNode("p",-1 /* HOISTED */) export function render(_ctx,[ _hoisted_1,_hoisted_2,1 /* TEXT */) ])) }
可以看到開啟了靜態提升後,直接將那兩個內容為helloworld的p標籤宣告在外面了,直接就拿來用了,這麼搞的話那肯定會快啊
事件偵聽器快取
預設情況下onClick會被視為動態繫結,所以每次都會去追蹤它的變化
但是因為是同一個函式,所以沒有追蹤變化,直接快取起來複用即可
dom結構
<div> <button @click = 'onClick'>點我</button> </div>
開啟事件偵聽器快取之前:
export const render = /*#__PURE__*/_withId(function render(_ctx,[ _createVNode("button",{ onClick: _ctx.onClick },"點我",8 /* PROPS */,["onClick"]) // PROPS=1<<3,// 8 //動態屬性,但不包含類名和樣式 ])) })
這裡有一個8,表示著這個節點有了靜態標記,有靜態標記就會進行diff演算法對比差異,所以會浪費時間
開啟事件偵聽器快取之後:
export function render(_ctx,{ onClick: _cache[1] || (_cache[1] = (...args) => (_ctx.onClick(...args))) },"點我") ])) }
可以發現,開啟事件偵聽器快取後,沒有靜態標記了,這就快了好多嘛
到此這篇關於Vue3為什麼這麼快的文章就介紹到這了,更多相關Vue3 快內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!