Yesterday SAW uVU live broadcast, Vue3 core Typescript, Proxy responsive, Composition solution code repeatedly horizontal jump has a great article analysis, I summarize the virtual Dom part, and compare React, vDOM rewriting is also an important reason why Vue3 ‘performance is so good

  1. Understand Vue3 source code this one is enough
  2. What’s so great about Vue 3.0? (Comparison of update principles)

First of all, static markers can improve upADTE performance by 1.3~2 times and SSR performance by 2~3 times. How can this be done

Static tags for compiling templates

Let’s look at a very common piece of code

<div id="app">
    <h1>Technology to touch the fish</h1>
    <p>It's a nice day today</p>
    <div>{{name}}</div>

</div>

Copy the code

This is resolved in VUe2

function render() {
  with(this) {
    return _c('div', {
      attrs: {
        "id": "app"
      }
    }, [_c('h1', [_v("Technology")]), _c('p', [_v("It's a beautiful day.")]), _c('div', [_v(
      _s(name))])])
  }
}

Copy the code

The first two tags are completely static and will not change in subsequent rendering. Vue2 still uses the _c newly built VDOM, which requires comparison during diff, resulting in some additional performance loss

Let’s take a look at the parsing results in VUe3

import { createVNode as _createVNode, toDisplayString as _toDisplayString, openBlock as _openBlock, createBlock as _createBlock } from "vue"

export function render(_ctx, _cache) {
  return (_openBlock(), _createBlock("div", { id: "app" }, [
    _createVNode("h1".null."Technology"),
    _createVNode("p".null."It's a beautiful day."),
    _createVNode("div".null, _toDisplayString(_ctx.name), 1 /* TEXT */)))}// Check the console for the AST

Copy the code

The final _createVNode and the fourth parameter, 1, are tracked only when they are used. Static nodes do not need to be traversed. This is the main source of vue3’s excellent performance

<div id="app">
    <h1>Technology to touch the fish</h1>
    <p>It's a nice day today</p>

    <div>{{name}}</div>
    <div :class="{red:isRed}">Fishing in character</div>
    <button @click="handleClick">Poking me</button>
    <input type="text" v-model="name">
    
</div>

Copy the code

Preview the results of parsing online

import { createVNode as _createVNode, toDisplayString as _toDisplayString, openBlock as _openBlock, createBlock as _createBlock } from "vue"

export function render(_ctx, _cache) {
  return (_openBlock(), _createBlock("div", { id: "app" }, [
    _createVNode("h1".null."Technology"),
    _createVNode("p".null."It's a beautiful day."),
    _createVNode("div".null, _toDisplayString(_ctx.name), 1 /* TEXT */),
    _createVNode("div", {
      class: {red:_ctx.isRed}
    }, "Touch fish symbol".2 /* CLASS */),
    _createVNode("button", { onClick: _ctx.handleClick }, "Poking me".8 /* PROPS */["onClick"]]))}// Check the console for the AST

Copy the code

_createVNode () < div style = “border-box: none; border-box: none; border-box: none; border-box: none; border-box: none; border-box: none; border-box: none; border-box: none; border-box: none; border-box: none; border-box: none; border-box: none; border-box: none; border-box: none; border-box: none; border-box: none; border-box: none Take a look at the notes that dissuade the big brothers

export const enum PatchFlags {
  
  TEXT = 1.// Represents an element with a dynamic textContent
  CLASS = 1 << 1.// represents an element with a dynamic Class
  STYLE = 1 << 2.// static (e.g. Style ="color: red")
  PROPS = 1 << 3.// represents an element with non-class/style dynamic items.
  FULL_PROPS = 1 << 4.// Represents the element of an item with a dynamic key, which is incompatible with the above three
  HYDRATE_EVENTS = 1 << 5.// Represents an element with an event listener
  STABLE_FRAGMENT = 1 << 6.// indicates a fragment whose child order is invariant.
  KEYED_FRAGMENT = 1 << 7.// represents a fragment with keyed or partially keyed child elements.
  UNKEYED_FRAGMENT = 1 << 8.// represents a fragment with a keyless binding
  NEED_PATCH = 1 << 9.// Indicates that only elements that are not attribute patches are required, such as ref or hooks
  DYNAMIC_SLOTS = 1 << 10.// represents an element with a dynamic slot
}
Copy the code

If we have both props and text bindings, we can use a bit-operation combination

<div id="app">
    <h1>Technology to touch the fish</h1>
    <p>It's a nice day today</p>
    <div :id="userid"">{{name}}</div>
</div>


Copy the code
import { createVNode as _createVNode, toDisplayString as _toDisplayString, openBlock as _openBlock, createBlock as _createBlock } from "vue"

export function render(_ctx, _cache) {
  return (_openBlock(), _createBlock("div", { id: "app" }, [
    _createVNode("h1".null."Technology"),
    _createVNode("p".null."It's a beautiful day."),
    _createVNode("div", {
      id: _ctx.userid,
      "\" ": ""
    }, _toDisplayString(_ctx.name), 9 /* TEXT, PROPS */["id"]]))}// Check the console for the AST

Copy the code

Text is 1, and props is 8, and when combined, it is 9. We can simply use bit operations to determine whether the text and props need to be compared

code

export const PLUGIN_EVENT_SYSTEM = 1;
export const RESPONDER_EVENT_SYSTEM = 1 << 1;
export const USE_EVENT_SYSTEM = 1 << 2;
export const IS_TARGET_PHASE_ONLY = 1 << 3;
export const IS_PASSIVE = 1 << 4;
export const PASSIVE_NOT_SUPPORTED = 1 << 5;
export const IS_REPLAYED = 1 << 6;
export const IS_FIRST_ANCESTOR = 1 << 7;
export const LEGACY_FB_SUPPORT = 1 << 8;

Copy the code

Event caching

The binding @click will be stored in the cache link

<div id="app">
  <button @click="handleClick">Poking me</button>
</div>

Copy the code
export function render(_ctx, _cache) {
  return (_openBlock(), _createBlock("div", { id: "app" }, [
    _createVNode("button", {
      onClick: _cache[1] || (_cache[1] = $event= > (_ctx.handleClick($event)))
    }, "Poking me")))}Copy the code

The incoming event automatically generates and caches an inline function and becomes a static node in the cache. This way, even if we write our own inline functions, it won’t cause unnecessary duplicate rendering

Static ascension

code

<div id="app">
    <h1>Technology to touch the fish</h1>
    <p>It's a nice day today</p>
    <div>{{name}}</div>
    <div :class="{red:isRed}">Fishing in character</div>
</div>

Copy the code
const _hoisted_1 = { id: "app" }
const _hoisted_2 = _createVNode("h1".null."Technology".- 1 /* HOISTED */)
const _hoisted_3 = _createVNode("p".null."It's a beautiful day.".- 1 /* HOISTED */)

export function render(_ctx, _cache) {
  return (_openBlock(), _createBlock("div", _hoisted_1, [
    _hoisted_2,
    _hoisted_3,
    _createVNode("div".null, _toDisplayString(_ctx.name), 1 /* TEXT */),
    _createVNode("div", {
      class: {red:_ctx.isRed}
    }, "Touch fish symbol".2 /* CLASS */)))}Copy the code

Vdom for VUE3 and React Fiber

Many people joke that React is becoming more and more like the API, which represents the two directions of the front end

Vue1.x

There is no VDOM, completely responsive, each data change, through the responsive notification mechanism to new Watcher work, just like when the independent group was small, each soldier enlisted and promoted, all take the initiative to inform our old Li, convenient management

As the project grows in size, too many Watchers can lead to performance bottlenecks

React15x

In the era of Act15, there was no responsiveness, the data changed, the whole new data and the old data diff, calculate the difference, then you know how to modify the DOM, just like the command room of Lao Li had a model, every personnel change, by comparing all the differences, you know the change, it seems that there is a lot of calculation. But this IMmutable data structure is more friendly to large projects, and after the success of Vdom abstraction, it is possible to switch to other platform render, whether playing the Devils or playing the national army, using a Vdom mode

The same problem is that if dom nodes continue to multiply and each diff takes longer than 16ms, it can cause stuttering (60fps).

Vue2.x

The introduction of VDOM, control the granularity, component level to go through the Watcher notification, components inside the VDOM to do diff, neither too much watcher, also will not let the size of the VDOM is too large, the diFF over 16ms, is really excellent ah, just like the independent regiment after large, only the battalion commander level changes, will notify Li. Internal diff managed by itself

React 16 Fiber

React goes the other way. Since the main problem is that diff causes a lag, React goes the other way, using CPU scheduling logic to make the vdom tree into a linked list, using the browser’s idle time to do diff. If it is longer than 16ms and there is an animation or user interaction task, the main process control is returned to the browser. Idle to continue, especially like waiting for the goddess’s spare tire

The diff logic becomes a one-way linked list, and whenever the main thread goddess is free, we’re just going to continue to get up and do diff, and if you look at requestIdleCallback, that’s what it looks like from a browser point of view

About the code

requestIdelCallback(myNonEssentialWork);
// Wait for the goddess to be free
function myNonEssentialWork (deadline) {
    // deadline.timeremaining ()>0
    // There are diff missions left unplayed
    while (deadline.timeRemaining() > 0 && tasks.length > 0) {
    doWorkIfNeeded();
    }
    // Goddess is out of time, return goddess 🤣
    if (tasks.length > 0){ requestIdleCallback(myNonEssentialWork); }}Copy the code

Vue3

ShouldComponentUpdate shouldComponentUpdate should change the default component to Pure or Memo. This is not the only way to implement static markup and event caching. Maybe this is life

React gives you freedom, while Vue makes you last, which is probably why both Vue and React are so popular in China

Vue3 uses Proxy responsiveness + component internal VDOM + static markup to control the granularity of the task sufficiently that time-slice is not necessary

In life, kids study the pros and cons every day, adults choose me, and I look forward to the new features of Act17

Live details

At the end of the q&A period, I couldn’t avoid the problem of hair volume, unfortunately, I didn’t recommend any hair conditioner. I looked at it carefully, it seems that after vuE3 was released, you really improved your hairline. I wish you can have black hair while improving your technology