And vue2 0 compared to vue3 What are the highlights of 0:
Serial number | characteristic | analysis |
---|---|---|
1 | Performance | Better performance than vue2 0 is 1.3-2 times faster |
2 | Tree shaking support | On demand compilation, lighter volume |
3 | Composition API | Composite API, similar to ReactHooks |
4 | Better TypeScript support | Better support for Ts |
5 | Custom Renderer API | Exposed custom rendering API |
6 | Fragment,Teleport(Protal),Suspense | More advanced components |
Vue3. How can 0 be lighter and faster?
1.diff algorithm optimization
The virtual Dom in Vue 2 is a full volume comparison
Vue 3 adds a static flag (PatchFlag)
After data changes, only nodes marked with PatchFlag are compared with the last virtual DOM node
And you can know the specific content to be compared from the flag information.
For example, the following code:
<div> <p>Li Bai will go by boat</p> <p>Suddenly I heard the sound of stepping on the shore</p> <p>Taohuatan is a thousand feet deep</p> <p>{{msg}}</p> </div>
In vue3 0 will be compiled into:( Online compilation address)
import { createVNode as _createVNode, toDisplayString as _toDisplayString, openBlock as _openBlock, createBlock as _createBlock } from "vue" export function render(_ctx, _cache, $props, $setup, $data, $options) { return (_openBlock(), _createBlock("div", null, [ _createVNode("p", null, "Li Bai will go by boat"), _createVNode("p", null, "Suddenly I heard the sound of stepping on the shore"), _createVNode("p", null, "Taohuatan is a thousand feet deep"), _createVNode("p", null, _toDisplayString(_ctx.msg), 1 /* TEXT Type flag is marked as 1 */) ])) }
[appendix: tag list]
TEXT = 1,// --The value is 1 --- indicates the element with dynamic textContent CLASS = 1 << 1, // --The value is 2 --- indicates the element with dynamic Class STYLE = 1 << 2, // --The value is 4 --- indicates the dynamic style (static, such as style="color: pink", will also be promoted to dynamic) PROPS = 1 << 3, // --The value is 8 --- indicates the element with non class / style dynamic props. FULL_PROPS = 1 << 4, // --The value is 16 --- the element of a prop with a dynamic key, which is exclusive of the above three HYDRATE_EVENTS = 1 << 5, // --The value is 32 --- indicates an element with an event listener STABLE_FRAGMENT = 1 << 6, // --The value is 64 --- it means that the sub order is unchanged and the self order will not be changed. KEYED_FRAGMENT = 1 << 7, // --The value is 128 --- indicates a fragment with keyed or partially keyed sub elements. UNKEYED_FRAGMENT = 1 << 8, // --The value is 256 --- fragment s without key binding of child nodes NEED_PATCH = 1 << 9, // --The value is 512 --- indicates that only non attribute patch elements are required, such as ref or hooks DYNAMIC_SLOTS = 1 << 10, // --The value is 1024 --- indicates the element with dynamic slot
2.hoistStatic static lifting
vue2.0, when updated, the element is recreated for rendering even if it does not change
vue3.0, elements that do not participate in update; It will be promoted statically, only created once, and reused directly in the next rendering.
So in vue3 0 has more reuse, fewer creation times and faster speed.
<div> <p>Li Bai will go by boat</p> <p>Suddenly I heard the sound of stepping on the shore</p> <p>Taohuatan is a thousand feet deep</p> <p>{{msg}}</p> </div>
Before static lifting:
export function render(_ctx, _cache, $props, $setup, $data, $options) { return (_openBlock(), _createBlock("div", null, [ _createVNode("p", null, "Li Bai will go by boat"), _createVNode("p", null, "Suddenly I heard the sound of stepping on the shore"), _createVNode("p", null, "Taohuatan is a thousand feet deep"), _createVNode("p", null, _toDisplayString(_ctx.msg), 1 /* TEXT */) ])) }
After static lifting:
// Note here that elements that do not need to be updated are created only once and are referenced directly later const _hoisted_1 = /*#__PURE__*/_createVNode("p", null, "Li Bai will go by boat", -1 /* HOISTED */) const _hoisted_2 = /*#__PURE__*/_createVNode("p", null, "Suddenly I heard the sound of stepping on the shore", -1 /* HOISTED */) const _hoisted_3 = /*#__PURE__*/_createVNode("p", null, "Taohuatan is a thousand feet deep", -1 /* HOISTED */) export function render(_ctx, _cache, $props, $setup, $data, $options) { return (_openBlock(), _createBlock("div", null, [ _hoisted_1, // Direct reference _hoisted_2, // Direct reference _hoisted_3, // Direct reference _createVNode("p", null, _toDisplayString(_ctx.msg), 1 /* TEXT */) ])) }
3.cachehandlers event listening cache
By default, onClick is treated as a dynamic binding, so it tracks its changes
The event bound function is the same, so it does not track its changes. It is directly cached and reused
<div> <button @click="onClick">Click the button</button> </div>
Before opening the cache:
export function render(_ctx, _cache, $props, $setup, $data, $options) { return (_openBlock(), _createBlock("div", null, [ _createVNode("button", { onClick: _ctx.onClick }, "Click the button", 8 /* PROPS */, ["onClick"]) ])) }
At this point, you can see that a flag with a value of '8' will be brought after compilation, which means that it will be tracked
After the cache is turned on:
export function render(_ctx, _cache, $props, $setup, $data, $options) { return (_openBlock(), _createBlock("div", null, [ _createVNode("button", { onClick: _cache[1] || (_cache[1] = (...args) => (_ctx.onClick && _ctx.onClick(...args))) }, "Click the button") ])) }
At this point, there is no mark and will no longer be tracked
4.ssr rendering
When there is a large amount of static content, it will be pushed into a buffer as a pure string. Even if there is a dynamic binding, it will be embedded through template interpolation. This will be much faster than rendering through virtual dmo.
When the static content is large to a certain magnitude, it will be used_ The createStaticVNode method generates a static node on the client side. These static nodes will be directly innerHtml, so there is no need to create an object, and then render according to the object.