Why virtual DOM?

Vue introduced the virtual DOM in version 2.0, which was considered revolutionary because the virtual DOM greatly improved page rendering speed.

What virtual DOM?

The virtual DOM is a JavaScript object that is a map of the actual DOM elements of the page in JavaScript execution memory, with the virtual DOM binding to data states (that is, data variables used in the Vue) rather than real DOM elements.

HOW virtual DOM?

Template compilation parses and compiles the template of the Vue instance and generates a rendering function from which we can build the virtual DOM.

For template compilation to generate rendering functions, see my other article: Vue source code analysis ② template compilation

Now let’s start analyzing the source code to see how rendering functions generate the virtual DOM, and how the virtual DOM (collectively called VNode) can improve the rendering speed of Vue applications.

Generate VNode

As mentioned above, vNodes are actually generated by executing render functions, so let’s take a look at how the render functions are executed:

The format of the render function is usually:

with(obj){
    return _c('div',
              [
        		_c('h1',
                   {
                      style({fontSize: title.size})
                   },
                   [
                      _v(_s(title.text))
                   ]),
                   _v(_s(content))
              ])
}
Copy the code

Where _c is the primary method used to form a plain VNode, _v is used to generate a text VNode, and _s is used to parse out the value of an expression.

_c basically calls the constructor of VNode, which generates an instance of VNode using information from our rendering function, such as tag, attrs, and children.

We can look at the VNode constructor:

var VNode = function VNode (tag, data, children, text, elm, context, componentOptions, asyncFactory) {
    this.tag = tag;
    this.data = data;
    this.children = children;
    this.text = text;
    this.elm = elm;
    this.ns = undefined;
    this.context = context;
    this.fnContext = undefined;
    this.fnOptions = undefined;
    this.fnScopeId = undefined;
    this.key = data && data.key;
    this.componentOptions = componentOptions;
    this.componentInstance = undefined;
    this.parent = undefined;
    this.raw = false;
    this.isStatic = false;
    this.isRootInsert = true;
    this.isComment = false;
    this.isCloned = false;
    this.isOnce = false;
    this.asyncFactory = asyncFactory;
    this.asyncMeta = undefined;
    this.isAsyncPlaceholder = false;
  };
Copy the code

In fact, it is just setting the values of each attribute, without any logical operation.

The use of the VNode

When we build a VNode, we’ll definitely use it to render to a real page. Here’s how:

For the first time to render

When the node is rendered for the first time, that is, the node is used for the first time after the Vue application starts, we provide VNode directly to create the actual DOM element and insert it into the page, and we are done rendering the VNode.

The second render

The second rendering means that when we render a VNode, the VNode has already been rendered before, and the old VNode has generated real DOM elements and exists in the page. Then we should patch the rendered new VNode and the old VNode to find out the differences. And delete some DOM elements in the page and insert the new DOM elements according to different points, the process is as follows:

let component = new Vue({
	el: '#app'.template: ` 
      

{{title}}

  • {{name}}
`
.data(){ return{ title: 'the title of Vue component'.list: ['Jhon'.'Judy'.'Sandy'] } } }) component.title = 'the new title of Vue component' component.list = ['Jhon'.'Jim'.'Judy'] Copy the code

We will conduct flow chart analysis of the above process:

After looking at the above flow chart, we may wonder why the li node in UL needs to be inserted in front of the node. Now let’s use the mind map to analyze:

The blue node is not processed, and the orange node is not processed