終端用戶感知明顯的是
-
性能優化
-
Tree-Shaking (搖枝算法)
我摘抄了PPT,看PPT就很詳細
Performance(性能優化)
-
Rewritten virtual dom implementation
-
考慮兼容性
-
對於庫作者,模板之外,脫離模板,實現邏輯複雜的渲染表達
-
-
Complier-informed fast paths
-
More effcient component initalization
-
1.3 - 2x better update performance
-
2 - 3x faster SSR*
all those thing based on benchmarks simulates typical scenarios ,may vary based on actual application
Tree-Shaking support
https://vue-next-template-explorer.netlify.app/
以上vue3最新的master commit 代碼來玩的玩具
如何使用vue-next-template-explorer
import { createVNode as _createVNode, toDisplayString as _toDisplayString, openBlock as _openBlock, createBlock as _createBlock } from "vue" export function render(_ctx, _cache) { return (_openBlock(), _createBlock("div", null, [ _createVNode("span", null, "static"), _createVNode("span", null, _toDisplayString(_ctx.msg), 1 /* TEXT */)//1 patchflag flag是編譯時生成的一個配置,只有帶patchflag的Node(節點)會被追蹤,比較text的文字變動 ])) }
<div> <span>static</span> <span> {{msg}} </span> </div>
舉例vue2渲染Dom的算法diff例子和vue3渲染Dom的例子
Vue2
<div> <span>static</span> <span>static</span> <span>static</span> <span> {{msg}} </span> <span>static</span> <span>static</span> <span>static</span> <span>static</span> </div>
默認渲染VirtualDom的diff算法是將整棵樹的style遍歷一次,每一個style的舊Props跟新的Props有什麼變化,js快,但是應用大了之後,消耗性能0
而vue3的diff算法是隻需檢查帶有patchflag的節點過一遍就是了
Vue3
<div> <span>static</span> <span>static</span> <span>static</span> <span> <span>{{msg}}</span> </span> <span>static</span> <span>static</span> <span>static</span> <span>static</span> </div>
哪怕這個span是經過嵌套的,vue3仍然不需要遍歷,因爲加入patchflag的節點會和block(div)節點綁定在一起,所以進入第一句(_openBlock(), _createBlock("div", null,之後就會找到綁定的節點,不需要遍歷其他
靜態ID綁定
<div> <span id='helloId'> {{msg}} </span> </div>
_createVNode("div", null, [ _createVNode("span", { id: "helloId" }, _toDisplayString(_ctx.msg), 1 /* TEXT */) ]),
靜態ID的綁定與雙向綁定text的方式無變化
動態ID綁定
<div> <span :id='helloId'> {{msg}} </span> </div>
_createVNode("div", null, [ _createVNode("span", { id: _ctx.helloId }, _toDisplayString(_ctx.msg), 9 /* TEXT, PROPS */, ["id"]) ]),
此時,patchflag產生變化,告訴我們不僅有text文字的變化還有屬性props的變化,並且向我們指明是屬性id動態變化,目的是讓動態更新的時候關注真正變化的東西
Cache Handlers(事件偵聽器的緩存)
<div> <span :id='helloId' @click='OnClick'> {{msg}} </span> </div>
//如果不選擇 Cache Handlers _createVNode("div", null, [ _createVNode("span", { id: _ctx.helloId, onClick: _ctx.OnClick }, _toDisplayString(_ctx.msg), 9 /* TEXT, PROPS */, ["id", "onClick"]) ]),
//使用Cache Handlers _createVNode("div", null, [ _createVNode("span", { id: _ctx.helloId, onClick: _cache[1] || (_cache[1] = $event => (_ctx.OnClick($event))) }, _toDisplayString(_ctx.msg), 9 /* TEXT, PROPS */, ["id"]) ]),
onClick: cache[1] || (cache[1] = $event => (_ctx.OnClick($event)))
如果當前緩存沒有,代表需要從$event傳遞進來,如果有緩存,直接找到緩存
支持手寫內聯函數
內聯函數也可以緩存進來,當然vue3這邊有做分析,至於如何分析,暫時不知道,尤雨溪有講,如果是在jsx裏面這樣寫,學過jsx之後,去和react做對比
<div> <span :id='helloId' @click='()=>foo()'> {{msg}} </span> </div>
_createVNode("div", null, [ _createVNode("span", { id: _ctx.helloId, onClick: _cache[1] || (_cache[1] = ()=>_ctx.foo()) }, _toDisplayString(_ctx.msg), 9 /* TEXT, PROPS */, ["id"]) ]),
Server Side Rendering
創建靜態的標籤直接使用字符串式,push進buffer流內,而不用一個一個去createElement
<div>Hello World!</div> <div>Hello World!</div> <div>Hello World!</div> <span>{{msg}}</span> <div>Hello World!</div> <div>Hello World!</div>
import { ssrInterpolate as _ssrInterpolate } from "@vue/server-renderer" export function ssrRender(_ctx, _push, _parent) { _push(`<!--[--><div>Hello World!</div><div>Hello World!</div><div>Hello World!</div><span>${_ssrInterpolate(_ctx.msg)}</span><div>Hello World!</div><div>Hello World!</div><!--]-->`) }
而當你的靜態節點嵌套得特別深入,也會創建出一個staticNode去優化
Tree-shaking
-
Most Optional features(e.g v-model,<transition>) are now tree-shakable
-
Bare-bone Hello World size:13.5kb;
-
11.75kb will only Composition API support;
-
-
All runtime features included:22.5kb;
-
More features but still lighter than Vue2 (開關去掉對2.0的支持)
-
treeshaking是通過編譯器去實現的,
Composition
尤雨溪並未講解,如有需求,可去https://composition-api.vuejs.org/網站查看,尤雨溪提及API Reference 中 Reactivity APIs的6個API纔是核心API
Fragment
對於模板用戶來說,肯定是無感知的。
模板只有一個根節點,在vue3裏面無需擁有根節點,可以多行文字,多個節點,而vue3會自動變成一個碎片。而如果用戶使用渲染函數,也可以直接在渲染函數中返回一個數組,自動變爲碎片
-
No Longer limited to a single root node in templates
-
Manual render functions can simply return Arrays
-
Just works
Teleport
接受一個disbaled參數,將本來應該傳送出去的東西駁斥回來,放在原來的渲染函數裏面,disalbed 用於響應式的設計,比如寬的屏幕展示出來,窄的屏幕拉回來。
多個Teleport 可以添加內容到同一個Compare裏面
-
Previously known as <Portal> React.Portal
-
More details to be shared by @Linusborg
Suspense
suspense 如何用在異步的請求裏面。可感知的性能提升是很低的,不作調度的情況下,也能做suspense
它可以在嵌套的組件樹渲染到屏幕上之前,可以在內存裏面進行渲染,可以檢測整顆樹裏面的異步依賴,只有當將整顆樹的異步依賴都渲染完成之後,也就是resolve之後,纔會將組件樹渲染到屏幕上去。
之前vue的做法並不是這樣,vue的組件嵌套是不會在乎你是否渲染完畢
vue3可以將async setup作爲異步原語,本身就是這樣來做,只要組件內部有一個async的setup函數就會認爲該組件是異步組件,也可以不跟suspense綁定
suspense主要是管理一些異步組件的加載也可以
-
Wait on nested async dependecies in a nested tree
-
Works with async setup()
-
Works with Async Components
Better Typescript support
-
Codebase written in TS w/auto-generated type defintions
-
API is the same in JS and TS
-
In fact ,code will also be largely the same
-
-
TSX support
-
Class components is still supported(vue-class-component@next) is currentty in alpha
針對vscode有插件
Custom Renderer API
vite
一個簡易的http
服務器,無需webpack
編譯打包,根據請求的Vue
文件,直接發回渲染,且支持熱更新(非常快)
之後就講了一些插件的作者和他們聯動更新,2.x如何兼容3.0 ,問題不大