Hello, I’m Karsong.

It is said that Chinese people pay attention to the golden mean. Do Chinese people pay attention to the artificial framework?

This article will explain from a theoretical level how Vue maintains a neutral balance between runtime and compile-time.

UI = fn(state)

How almost any front-end framework works can be summarized in the following formula:

UI = fn(state)
Copy the code

UI (view) can be computed by state via FN (frame).

However, the specific principle, between the framework is very different.

They can be divided into three categories by update granularity:

  • Update the tree level

  • Component-level update

  • Node-level update

There is no superior or inferior update granularity, just different implementations

Let’s take a brief look at the implementation principles of different granularity update methods.

Assume the following component tree, where Cpn is a custom component with ul> Li *2 internal structure:

We want to update a LI in Cpn to yellow:

Update the tree level

The framework of tree-level update will regenerate into a complete virtual DOM tree, which will be compared with corresponding nodes of the previous virtual DOM tree in the generation process:

After the changed node is found, the corresponding DOM operation is performed.

The characteristics of the tree-level update framework are:

  • Rely on the virtual DOM

  • Don’t care about the node that triggered the update (because it will be found through a full-tree comparison of the virtual DOM)

The most famous framework for this approach to updates is React.

Component-level update

The above example, if the component level update framework.

The component where the update node is triggered will be found, and the virtual DOM tree of the component will be generated (instead of the virtual DOM tree of the whole tree). During the generation process, it will be compared with the corresponding node of the virtual DOM tree before the component:

After the changed node is found, the corresponding DOM operation is performed.

The component-level update framework features:

  • Rely on the virtual DOM

  • Care about the node that triggers the update (the virtual DOM comparison is applied to the component where the node is located)

The most famous framework for this kind of update is Vue.

Node-level update

In the case of node-level update framework, corresponding methods will be generated directly according to DOM changes corresponding to state changes during compilation, and corresponding methods will be called directly after state changes.

In the example above, the color state is associated with the changeColor method at compile time:

function changeColor(newColor) {
  li.style.color = newColor;
}
Copy the code

When changing the color state, call changeColor to update the DOM corresponding to Li.

The characteristics of node-level update framework are as follows:

  • Don’t rely on the virtual DOM, rely on precompilation (establishing a link between state and methods to change the DOM)

  • Care about the node that triggered the update (the node state corresponds to the update method)

The most famous framework for this kind of update is Svelte.

The doctrine of the mean of Vue3

Vue represents component-level updates with granularity between tree level and node level. Is that left of center or right of center?

Vue3 said.

I’m gonna do it over and over again. I’m gonna do it both ways

Vue3 contains three tree-like structures:

Tree describing the view -> virtual DOM tree -> real DOM treeCopy the code

The tree describing the view is officially recommended to use template syntax, but JSX can also be used.

Either way, this will eventually translate into a virtual DOM tree.

When using JSX, Vue3 has the flexibility of the React runtime and can be seen as an enhanced version of React + Mobx

Vue3 introduces precompilation techniques when using template syntax. At this point, the Vue3 workflow can be broken down into four steps:

Describe the view tree -> VNode tree -> Block array -> real DOM treeCopy the code

The VNode tree is the virtual DOM tree in the general sense, and the Block array is the array of vNodes that are state-dependent and will change in the VNode tree.

For example, for the following template syntax:

<template>
  <section>
    <div>i am</div>
    <p>{{name}}</p>
  </section>
</template>
Copy the code

Sections and divs do not contain state and do not change, so they are converted to vNodes, but there is no corresponding Block.

P contains the state name, which is converted to vNodes and blocks.

When the component of the template triggers a name state change, vNodes of section, div, and P need to be created and compared.

With precompilation, you just walk through the Block array for comparison.

Using the above example, we only need to compare one LI node:

In this case, it’s a component-level update framework that uses the virtual DOM, but it’s pretty close to a node-level update framework.

conclusion

This article describes three different types of frameworks in terms of update granularity, as well as Vue3’s flexibility between flexibility and update granularity when choosing JSX and template syntax.

It’s a happy medium, so to speak.

One might ask that Vue3 users are mostly comfortable with template syntax, so why not just ditch the virtual DOM and use precompilation techniques for true node-level updates?

On the one hand, the virtual DOM removes the framework from the concrete view layer, making cross-side rendering easier.

On the other hand, the Vue2 community ecosystem has accumulated a large library based on virtual DOM.

What would you do if you were in that situation?