Vue virtual DOM diff

Time:2020-6-28
Virtual element node vnode

What is a virtual element node?
The virtual element node is the description of the real DOM node. Contains label name, label attribute description object, and child node collection.

// example
{
    tag:'div'
    props:{
        Key: 'UUID', // vnode unique key, useful when new and old vnode diff
        ID: 'div', // vnode ID value
        //...
    }
}

What are the advantages of virtual DOM?
Virtual DOM has batch processing and efficient diff algorithm, which can reduce rearrangement and redraw, and improve performance;

The idea of virtual DOM diff
  • Vnode change type:
Replace: replace the current node node. Comparison method: compare new and old nodes one by one at the same location. Structure:{ type:0 , node:newNode }。
Reorder: a new or deleted child node in the child node collection. Comparison method: set peer comparison of child nodes. Structure:{ type:1 ,moves:[{ type:0 ——Delete, index: the subscript} of the child node in the child node collection{ type:1 ——New, index: the subscript of the child node in the child node collection, item:newVNode }]}。
Props: the current node attribute changes. Comparison method: compare new and old nodes one by one at the same location. Structure:{ type:2 , props: [{modify propKey:undefined ——Delete the attribute, propKey:newPropValue }]}。
Text: the current node text node changes. Comparison method: compare new and old nodes one by one at the same location. Structure:{ type:3 , content:newText }。
  • Summary of the new and old virtual DOM diff ideas: because there are few cross level modifications that can be ignored, only the same level set of child nodes are compared.Vue virtual DOM diff
    Note: when comparing the new and old virtual DOM diffs, the recursive method is used, and the statistics are from top to bottom.

    • Save patches [key]:Key is the location of the node in the virtual DOM tree recursionIt is convenient to find the corresponding nodes when the patch is applied in the actual DOM tree.
    • Start with newvnodelist and oldvnodelistSame location (same index)Compare vnode of vnode, and count the changes of props, text and vnode replaced (inconsistent label name or unique key of vnode)
    • Go ahead againPeerCompare the child vnodelist and count the deletion and addition of child nodes. And return oldVNodeList.length A new array of length and vnode / text values in the newvnodelist. adoptVnode unique keyCarry out comparative statistics.
Compare the results of patches and apply them to real DOM

Note: when applying the comparative results patches to the real DOM, the recursive method is adopted and applied from the bottom to the top.

  • patch.type===0 (replace node): node.parentNode.replaceChild (newNode,oldNode)
  • patch.type===1 (delete and add child nodes): removechild (removenode), cloneNode (true), insertBefore (insertnode, beforenode)
  • patch.type===2 (props change): removeaattribute (prop), setAttribute (prop)
  • patch.type===3 (text change): elementNode.textContent , textNode.nodeValue

Reference website:
In depth analysis: how to implement a virtual DOM algorithm: https://github.com/livoras/blog/issues/13
First comparison code of vnodelist of the same level: https://github.com/livoras/list-diff/blob/master/lib/diff.js