12-Vue's diff algorithm

Reference answer:

When the component is created and updated , Vue will execute the internal update function . This function uses the virtual dom tree generated by the render function to compare the old and new trees, find the difference, and finally update to the real dom. The process of comparing the difference is called diff. Vue completes this process internally through a function called patch . When comparing, Vue uses depth-first and same-level comparison for comparison. When judging whether two nodes are the same, Vue judges through the key and tag of the virtual node . Specifically, first compare the root node , and if they are the same, hang the reference of the real DOM associated with the old node to the new node , and then update the attribute to the real dom as needed, and then compare its child node arrays; if they are not the same, recursively create all real doms according to the information of the new node, and hang them on the corresponding virtual nodes at the same time, and then remove the old dom. When comparing its sub-node arrays, vue uses two pointers for each sub-node array , pointing to the head and tail respectively, and then keeps moving closer to the middle for comparison. The purpose of this is to reuse the real dom as much as possible and destroy and save as little as possible. Create real dom. If they are found to be the same, enter the same comparison process as the root node, and if they are found to be different, move the real dom to a suitable position. This keeps recursive





The traversal continues until the entire tree is compared.

1. Timing of diff

When a component is created, or when a dependent property or data changes, a function is run that does two things:

  • Run  _render to generate a new virtual dom tree (vnode tree)
  • Run  _update, pass in the root node of the virtual dom tree, compare the old and new trees, and finally complete the update of the real dom

The core code is as follows:

// vue构造函数
function Vue(){
    // ... 其他代码
    var updateComponent = () => {
    this._update(this._render())
    }
    new Watcher(updateComponent)
    // ... 其他代码
}

diffhappens while _updatethe function is running

2. What does the _update function do

_updateThe function receives a vnodeparameter, which is the newly generated virtual dom tree

At the same time, the function gets the old virtual dom tree _updatethrough the properties of the current component_vnode

_updateThe function first _vnodereassigns the properties of the component to point to the new tree

function update (vnode) {
		// vnode 新
		// this._vnode  旧
	let oldVnode = this._vnode;
	this._vnode = vnode;
	// 对比的目的:更新真实dom
	if (!oldVnode) {
		this.__patch__(this.$el.vnode);
	}
}

Then it will judge whether the old tree exists:

  • Does not exist: It means that this is the first time to load the component, so through the internal patchfunction , directly traverse the new tree, generate a real DOM for each node, and mount it on elmthe property of each node
  • Existence: It means that the component has been rendered before, so through the internal patchfunction, compare the old and new trees to achieve the following two goals:

  • Complete the minimization of all real DOM

  • Let the nodes of the new tree correspond to the appropriate real dom

3. Comparison process of patch function

Explanation of terms :

  1. " Same ": refers to the label type and keyvalue of the two virtual nodes are the same, but inputthe element depends on typethe attribute
  2. " New element ": refers to creating a real dom element based on the information provided by a virtual node, and at the same time mount it on the elmattribute of the virtual node
  3. " Destruction Element " means:vnode.elm.remove()
  4. " Update ": refers to the comparative update of two virtual nodes, which only occurs when the two virtual nodes are "same". The specific process will be described later.
  5. " Comparing child nodes ": refers to comparing the child nodes of two virtual nodes, the specific process will be described later

Detailed process:

  1. root node comparison

patchThe function first compares the root node

If two nodes:

  • "Same", enter ** "Update" process**
  1. Assign the real dom of the old node to the new node:newVnode.elm = oldVnode.elm

  2. Compare the properties of the new node and the old node, and update the changed ones to the real dom

  3. The current two nodes are processed, start ** "Comparing child nodes"**

  • Are not the same"
  1. New node recursive "new element"

  2. Old node "Destroy Element"

  3. "Compare Child Nodes"

When "comparing child nodes", the starting point of all vue is to:

  • try not to do anything
  • If not, try to only change the element attribute
  • If not, try to move elements instead of deleting and creating elements
  • If not, delete and create elements

This article is reproduced from:

94.diff·Work FAQ·Kanyun

Guess you like

Origin blog.csdn.net/iaz999/article/details/131486639