VUE3.0 series: vue3 What's new for 0

Posted by osti on Sun, 23 Jan 2022 12:54:23 +0100

And vue2 0 compared to vue3 What are the highlights of 0:

Serial numbercharacteristicanalysis
1PerformanceBetter performance than vue2 0 is 1.3-2 times faster
2Tree shaking supportOn demand compilation, lighter volume
3Composition APIComposite API, similar to ReactHooks
4Better TypeScript supportBetter support for Ts
5Custom Renderer APIExposed custom rendering API
6Fragment,Teleport(Protal),SuspenseMore 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.

Topics: Front-end Vue