[Source code level] The bottom layer of the diff algorithm - and the role of the key

It took me a long time today to study the source code of the virtual dom and diff algorithm, summarize the information from various sources, and straighten out the entire logic myself, hoping to help everyone a little bit.

First, let’s talk about diff.
In fact, it is also an inevitable product of virtual dom technology. It is not dedicated to vue. Other frameworks, as long as virtual dom is involved, have diff algorithms. Because if we only modify a small part of it when we write the page, but if it is directly rendered to the real dom, and then reflowed and redrawn, the overhead is very high, but the lovely diff! Can help us only modify the small piece we update. The key can help us efficiently update the virtual dom. The function of the key will be discussed later.

Two, diff in vue.
Mainlyanalyze from the three modules of the necessity , execution and efficiency of diff.

1. Necessity - Why do we need diff algorithm?

First of all, we can see the method of the mountedcomponent of the source code lifecycle module.


When a component executes $mount once, a watcher will be created (the watcher corresponds to the component instance one by one). But there are likely to be multiple data in the component that use the key, but a vue2 component has only one watcher. In order to know who has changed during the update process more accurately, we need diff . (First, simply summarize diff as two comparisons of the old and new virtual doms, which can compare the changes, and give you an idea~)


2. Execution
Let's look at the source code, patchVnode, this is where the diff occurs. The patchVnode function  is used to compare the children of two identical nodes.
Occurrence time: when the instance of the component executes the update function.


Overall strategy: Depth first, same layer comparison.

In layman's terms, find the children first , and only after all the children are compared will you start to compare the next node at the same level as the changed node - find the difference.
I found a picture on the Internet, I hope it can help you understand. Please take a look, you can refer to the execution sequence .


Overall logic : from the source code, it mainly depends on whether both parties have children. No waiting, please look at the source code:



As for the above, briefly summarize the above two source codes:

Compare the two virtual dom trees, execute the patchvnode (comparison oldVnode, newVnode) function on the root node root, and compare whether the two root nodes are the same node. If they are different, replace them directly (add new ones, delete old ones).

②If they are the same, continue to patchVnode, and further compare attributes, text, and child nodes. To update, that is, to add, delete, and modify. Only when there are child nodes, and oldVnode === newVnode is false. (Insert a sentence: Because if they are congruent, it means that the children must be completely equal, which is nothing more, no need to compare) The updateChildren function will be executed to further compare their child nodes

3. Efficiency---- Compared to children- -- updateChildren function -----deeply compare the child nodes of the old and new nodes

③Assume that the head and the tail are the same and do four comparisons (the new and old start and end are reorganized back and forth). The situation is dealing with the rest. .
(During head-to-tail comparison) the key can be used to accurately find the same node, so as to find the exact position to insert the new node . The patch process will be very efficient .
If no key is added, it will always be regarded as the same node, and the only operations that can be performed are hard updates , which cannot avoid frequent update processes, many DOM operations, and poor performance.

In short, it reflects a recursive cycle:
patch —> patchVnode —> updateChildren —> patchVnode —> updateChildren —> patchVnode…

Finally, insert a sentence about key:
key is the unique identifier of vnode, and it is immutable. For example, when we code the code, set the unique student number, id, and ID number.

The role of the key is to update the virtual dom more efficiently (improving rendering efficiency), that is, the diff algorithm. For example, if we want to add a D in the middle of bc, the key can be used as the unique identifier of the node, telling diff that it is the same node before and after the change. Find the correct position to insert the new node.
Be careful not to use index, because for example, if data is inserted in the middle, the label of the data stream will change, and the index will change, which will not only reduce the efficiency of the key. If it is serious, it will directly render an error.

Guess you like

Origin blog.csdn.net/m0_71981318/article/details/125539115