Vue3’s core Typescript, Proxy responsiveness, Composition solutions and repeated crossoverings have all been dissected in great articles. I’ll summarize the virtual Dom section and compare it to React. The VDOM rewrite is also a big reason why Vue3 performs so well
Overall especially the process of live broadcast, a few big brothers have summed up the thief stick, move directly
- This article is enough to understand the Vue3 source code
- Vue 3.0 this charming little goblin, what is good in the end? (Update principle comparison)
- Note: Yuyuxi talked about this in Vue3.0 Beta…
The virtual DOM of Vue3
First of all, the conclusion is that with static marker, upadTE performance is improved by 1.3~2 times, and SSR performance is improved by 2~3 times. How to do it
The static tag for compiling the template
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
It is analyzed in VUE2
function render() {
with(this) {
return _c('div', {
attrs: {
"id": "app"
}
}, [_c('h1', [_v("Technical fish")]), _c('p', [_v("It's a beautiful day today.")]), _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 _C newly built VDOM, which needs to be compared during diff, which has some additional performance loss
Let’s 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."Technical fish"),
_createVNode("p".null."It's a beautiful day today."),
_createVNode("div".null, _toDisplayString(_ctx.name), 1 /* TEXT */)))}// Check the console for the AST
Copy the code
The fourth parameter of the last _createVNode, 1, is only truly tracked. 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
The results of parsing are previewed 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."Technical fish"),
_createVNode("p".null."It's a beautiful day today."),
_createVNode("div".null, _toDisplayString(_ctx.name), 1 /* TEXT */),
_createVNode("div", {
class: {red:_ctx.isRed}
}, "Touch the fish".2 /* CLASS */),
_createVNode("button", { onClick: _ctx.handleClick }, "Poking me".8 /* PROPS */["onClick"]]))}// Check the console for the AST
Copy the code
_createVNode: props, props, props, props, props, props, props Take a cue from the quitters
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.// Represent dynamic styles (static, such as style="color: red", will also be promoted to dynamic)
PROPS = 1 << 3.// represents an element with a non-class/style dynamic item.
FULL_PROPS = 1 << 4.// An element that represents an item with a dynamic key, which is opposed to the three above
HYDRATE_EVENTS = 1 << 5.// Represents an element with an event listener
STABLE_FRAGMENT = 1 << 6.// represents a fragment whose suborder is unchanged.
KEYED_FRAGMENT = 1 << 7.// represents a fragment with keyed or partially keyed child elements.
UNKEYED_FRAGMENT = 1 << 8.// represents a fragment with no key binding
NEED_PATCH = 1 << 9.// indicates that only elements that are not attribute fixes are required, such as refs or hooks
DYNAMIC_SLOTS = 1 << 10.// represents an element with a dynamic slot
}
Copy the code
If you have both props and text bindings, you can use the 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."Technical fish"),
_createVNode("p".null."It's a beautiful day today."),
_createVNode("div", {
id: _ctx.userid,
"\" ": ""
}, _toDisplayString(_ctx.name), 9 /* TEXT, PROPS */["id"]]))}// Check the console for the AST
Copy the code
Text is 1, props is 8, and the combination is 9. We can use bitwise operation to determine whether to use text and props. As long as it is not 0, we need to compare
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 bound @click link will be cached
<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 is automatically generated and cached as an inline function and then cached as a static node. This way, even if we write our own inline functions, we don’t have to repeat the render
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."Technical fish".- 1 /* HOISTED */)
const _hoisted_3 = _createVNode("p".null."It's a beautiful day today.".- 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 the fish".2 /* CLASS */)))}Copy the code
Vdom for VuE3 and React Fiber
A lot of people talk about it being more and more like React, but it’s actually more and more like an API, representing both directions of the front end
Vue1.x
No VDOM, completely responsive, every data change, through a responsive notification mechanism for new Watcher work, just like the independent regiment size, every soldier enlisted and promoted, proactively notified our Old Li, easy to manage
As the project gets larger, too many Watcher can lead to performance bottlenecks
React15x
In the era of React15, there was no response, and the data changed. Diff the whole new data and the old data, calculate the difference, and then know how to modify the DOM. Just like Old Li’s command room has a model, every personnel change, by comparing the difference of all the people before and after, we know the change, which seems to involve 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 change to other platform render, whether it is to fight the devil or the military, with a Vdom mode
If the number of DOM nodes continues to increase and the diff time exceeds 16ms, it may cause a lag (60fps).
Vue2.x
Vdom was introduced to control the granularity, watcher notifications were made on the component level, and DIff was made on the component internal VDOM, so there would not be too many Watcher, and the size of VDOM would not be too large. The DIFF would exceed 16ms. It is really excellent, just like when the independent regiment became large, only the battalion commander and platoon commander level would be notified to Li. Internal diff managed by itself
React 16 Fiber
React went the other way. Since the main problem was diff causing the lag, React went the same way as CPU scheduling, turning the VDOM tree into a linked list, using the browser’s free time to do diff, and giving the browser control of the main process back if there was animation or user interaction over 16ms. Wait for idle to continue, especially like waiting for a goddess’s spare tire
Diff logic becomes a one-way linked list. Whenever the main thread is free, we will continue to do diff. If you look at requestIdleCallback, it will look like this from the browser’s perspective
About the code
requestIdelCallback(myNonEssentialWork);
// Wait for the goddess to be idle
function myNonEssentialWork (deadline) {
// deadline.timeremaining ()>0
// Diff is not a game
while (deadline.timeRemaining() > 0 && tasks.length > 0) {
doWorkIfNeeded();
}
// The goddess is running out of time, return the goddess to 🤣
if (tasks.length > 0){ requestIdleCallback(myNonEssentialWork); }}Copy the code
Vue3
If the React component shouldComponentUpdate component is defined by itself, why not change the default component to pure or memo? If the React component shouldComponentUpdate component is defined by itself? Maybe this is life
React gives you freedom and Vue makes you last, which is probably why both Vue and React are so popular in China now
With Proxy response + component internal VDOM + static markup, Vue3 controls the granularity of tasks in sufficient detail, so there is no need for time-slice
Life ah, only children study pros and cons every day, adults choose I want, but also look forward to React17 new features
Live broadcast details
During the final question period, I can’t avoid the problem of hair quantity, but I didn’t recommend what hair conditioner. I took a close look at it, and it seems that after the release of VUE3, the hairline of vuE3 has indeed improved. I wish you can have black hair while improving your technology
Small AD
Welcome to like attention, my main hobby is to touch fish, recommend a fish, this article is my morning to touch fish to write out, together with the technology to touch fish, recently ready to touch fish to write a VUE3 source code full analysis series