Following the crowd doesn’t make you better, it makes you more and more conform.

When you talk to other developers about the Vue 3.0 release, one of your answers will be “it’s faster, it’s 1.2 to 2 times faster”.

So I’d like to ask you what makes Vue faster, and You’ve already told us the answer in a live stream of the beta.

PatchFlag(Static flag)

The virtual DOM in Vue 2.x is the mode of full comparison, and since Vue 3.0, PatchFlag has been added.

When comparing pre-update nodes, only nodes with static tags will be compared. In addition, the PatchFlag enumeration defines more than a dozen types, which can be used to accurately locate the types of nodes to be compared. Below we analyze the process of this comparison through graphic examples.

Suppose we have the following code:

<div>
  <p>The old eight canteen</p>
  <p>{{ message }}</p>
</div>
Copy the code

In the full contrast mode of Vue 2.x, it is shown in the figure below:

From the figure above, we can find that the DIff algorithm of Vue 2.x compares each tag once, and finally finds that the tag with {{message}} variable is the one that needs to be updated. Obviously, there is room for optimization.

In Vue 3.0, the DIFF algorithm is optimized. When creating the virtual DOM, according to whether the DOM content will change, the corresponding type of static flag (PatchFlag) is given, as shown below:

Looking at the figure above, it is not difficult to see that the attempted update only compares the tags with flags (diff), so only one comparison is made, while Vue 2.x compares three times in the same case. This is the first reason why Vue 3.0 performs better than Vue2.x.

We verify our analysis by translating the template code into the virtual DOM. We can open the template conversion website and translate the above code:

The blue box in the figure above shows the translated virtual DOM node. The first P tag is a static TEXT, while the second P tag is a bound variable, so the tag 1 is marked, which represents TEXT. The tag enumeration type is as follows:

export const enum PatchFlags {
  
  TEXT = 1.// Dynamic text node
  CLASS = 1 << 1.// 2 Dynamic class
  STYLE = 1 << 2.// 4 Dynamic style
  PROPS = 1 << 3.// 8 Dynamic properties, excluding class names and styles
  FULL_PROPS = 1 << 4.// 16 Dynamic key. When the key changes, the full diff algorithm is required for comparison
  HYDRATE_EVENTS = 1 << 5.// 32 represents the node with event listeners
  STABLE_FRAGMENT = 1 << 6.// 64 A Fragment that does not change the order of the child nodes
  KEYED_FRAGMENT = 1 << 7.// 128 Fragment with key attribute
  UNKEYED_FRAGMENT = 1 << 8.// 256 The child node has no Fragment with a key
  NEED_PATCH = 1 << 9./ / 512
  DYNAMIC_SLOTS = 1 << 10./ / dynamic solt
  HOISTED = -1.// The special flag is a negative integer to indicate that it will never be used as diff
  BAIL = -2 // A special flag refers to the difference algorithm
}
Copy the code

hoistStatic(static promotion)

We usually write a function in the development process, when some write dead variables, will promote the variable definition, as follows:

const PAGE_SIZE = 10
function getData () {
	$.get('/data', {
  	data: {
    	page: PAGE_SIZE }, ... })}Copy the code

For example, if you write PAGE_SIZE = 10 inside the getData method, the variable will be redefined every time getData is called.

Vue 3.0 makes the same optimization in this area, continuing with the code we wrote in the previous example, and observing the compiled virtual DOM structure is as follows:

Before doing static lift:

Select hoistStatic under Option:

After static lifting:

If you are careful, you will notice that the function is outside the render function, so just use the _hoisted_1 variable every time you render. If you read the article carefully, you will notice that _hoisted_1 is marked with PatchFlag, and the static value is -1. The special flag is a negative integer to indicate that it will never be used as Diff. In other words, those marked -1 will not participate in the Diff algorithm, which improves the performance of Vue.

CacheHandler = event listener

By default, the @click event is considered a dynamic variable, so it is tracked every time the view is updated. But normally, our @click event is the same event before and after the view is rendered, so there is little need to track its changes, so Vue 3.0 has made a corresponding optimization called the event listener cache. We add the following section to the above code:

<div>
  <p @click="handleClick">The house a giao</p>
</div>
Copy the code

When compiled, it looks like this (with cacheHandler not enabled) :

With the event listening cache not enabled, we see that this string of code is compiled and statically marked as 8. As explained earlier, the statically marked tag is pulled for comparison, and the static tag 8 corresponds to “dynamic properties, excluding class names and styles.” @click is considered a dynamic property, so we need to enable the cacheHandler property under Options, as shown in the figure below:

Careful students will also notice that after cacheHandler is enabled, the compiled code has no static flag, which means that the P tag in the diagram is no longer tracked and compared, thus improving Vue performance.

SSR server rendering

When you use SSR in development, Vue 3.0 will convert static tags directly to text. Compared to React, which first converts JSX to virtual DOM and then virtual DOM to HTML, Vue 3.0 has won.

StaticNode

The SSR server renders the static label directly into text. When the client renders, as long as the tags are nested enough, they are also converted to HTML strings at compile time, as shown below:

You need to enable hoistStatic under Options

conclusion

The above is the performance optimization of Vue3.0 for the virtual DOM at compile time, which makes Vue3.0 1.2 ~ 2 times better than Vue 2.x.

Vue3-examples creates a Vue3 learning repository, vue3-examples, github.com/newbee-ltd/… , this warehouse will not regularly update a variety of Vue3.0 related knowledge and a variety of integration of Demo and Vue3 use tips, you can pay attention to, what suggestions are also welcome to give me a message.

In addition to indicate the reprint/source, all are the author’s original, welcome to reprint, but without the consent of the author must retain this paragraph of statement, and in the article page clearly given the original link, or reserve the right to seek legal responsibility.