Understanding of virtual DOM in Vue

Understanding of virtual DOM in Vue

Virtual DOM is a tree based on JavaScript objects. Each node is called VNode, and the node is described by object attributes. In fact, it is an abstraction of the real DOM. Finally, the tree can be mapped to the real DOM through rendering operations. In a real environment, Virtual DOM is simply a Js object that describes the entire document.

describe

DOM nodes are used to describe the entire document when building a page in the browser.

<div class="root" name="root">
    <p>1</p>
    <div>11</div>
</div>

If you use Js objects to describe the above nodes and documents, it will look like the following. Of course, this is not the object used to describe nodes in Vue. The object used to describe a node in Vue includes a large number of attributes, such as tag, data, children, text, elm, ns, context, key, componentOptions, componentInstance, parent, raw, isStatic, isRootInsert, isComment, isCloned, etc. For specific properties, please refer to /dev/src/core/vdom/vnode.js of Vue source code .

{
    type: "tag",
    tagName: "div",
    attr: {
        className: "root"
        name: "root"
    },
    parent: null,
    children: [{
        type: "tag",
        tagName: "p",
        attr: {},
        parent: {} /* parent node reference */, 
        children: [{
            type: "text",
            tagName: "text",
            parent: {} /* parent node reference */, 
            content: "1"
        }]
    },{
        type: "tag",
        tagName: "div",
        attr: {},
        parent: {} /* parent node reference */, 
        children: [{
            type: "text",
            tagName: "text",
            parent: {} /* parent node reference */, 
            content: "11"
        }]
    }]
}

In Vue, the HTML nodes and component nodes defined in the template are first parsed to prepare for rendering. During the parsing process, functions such as _c() and _v() are generated, which are used as renderHelpers to create nodes, _v() The function is used to create text nodes, and the _c() function is used to create VNode nodes. This function is actually the _createElement() function defined in Vue. This function is used to determine whether a normal node or a component node is created. Specifically, you can refer to /dev/src/core/vdom/create-element.js and /dev/src/core/vdom/create-element.js in the Vue source code. After the parsing is completed, the render function can be generated, and when the parsing is completed, the render function can be generated. After the render function is executed, it returns a virtual DOM tree composed of VNode nodes. Each node in the tree will store the information needed for rendering, and then render to the real DOM through the diff algorithm and createElm or patchVnode of the patch process.

if (typeof tag === 'string') {
let Ctor
ns = (context.$vnode && context.$vnode.ns) || config.getTagNamespace(tag)
if (config.isReservedTag(tag)) {
  // platform built-in elements
  if (process.env.NODE_ENV !== 'production' && isDef(data) && isDef(data.nativeOn)) {
    warn(
      `The .native modifier for v-on is only valid on components but it was used on <${tag}>.`,
      context
    )
  }
  vnode = new VNode(
    config.parsePlatformTagName(tag), data, children,
    undefined, undefined, context
  )
} else if ((!data || !data.pre) && isDef(Ctor = resolveAsset(context.$options, 'components', tag))) {
  // component
  vnode = createComponent(Ctor, data, context, children, tag)
} else {
  // unknown or unlisted namespaced elements
  // check at runtime because it may get assigned a namespace when its
  // parent normalizes children
  vnode = new VNode(
    tag, data, children,
    undefined, undefined, context
  )
}
} else {
// direct component options / constructor
vnode = createComponent(tag, data, context, children)
}

effect

The process of rendering the real DOM is very expensive. For example, when a certain data or attribute is sometimes modified, if it is directly rendered to the real DOM, it may cause the redraw and reflow of the entire DOM tree, and the diff algorithm can only update the modification. That part of the DOM structure does not update the entire DOM, what needs to be explained here is that the speed of operating the DOM structure is not slow, and the performance consumption is mainly in the operation of browser redraw and reflow.
When the diff algorithm is used for partial update, it is necessary to compare the difference between the old DOM structure and the new DOM structure. At this time, VNode is required to describe the entire DOM structure. First, the Virtual DOM is generated according to the real DOM. When the data of a node in the Virtual DOM changes After that, a new Vnode will be generated, and then the newVNode and oldVNode will be compared, and if there is a difference, the patch will be modified to the real DOM, and then the old Virtual DOM will be assigned to the new Virtual DOM.
Simply put, the purpose of creating a Virtual DOM is to reduce the operation of the entire DOM. By creating a Virtual DOM to track how to change the real DOM, update nodes more efficiently.
Using Virtual DOM also has some disadvantages, more code, larger volume, and increased memory usage. For a small amount of single DOM modification, the cost of using virtual DOM is higher, but overall, the advantages of using Virtual DOM are far greater than disadvantage.

Question of the day

https://github.com/WindrunnerMax/EveryDay

refer to

https://juejin.im/post/6844903607913938951
https://segmentfault.com/a/1190000018211084
https://github.com/lihongxun945/myblog/issues/32
https://cloud.tencent.com/developer/article/1004551
https://www.cnblogs.com/fundebug/p/vue-virtual-dom.html
https://blog.csdn.net/u010692018/article/details/78799335/

Tags: Vue

Posted by yeldarb on Wed, 25 May 2022 11:19:55 +0300