scenario
The structural differences of the two trees were calculated and converted
In this paper, n refers to the number of nodes
Traditional Diff algorithm
Solution: Iterate over each node
Traditional diff
As shown above, node A of the left tree is compared as follows:
A -> E, A -> D, A -> B, A -> C, A -> A
Then other nodes B, C, D and E of the left tree are compared with each node of the right tree, and the algorithm complexity can reach O(n^2).
After finding the difference, we also need to calculate the minimum transformation mode, the principle of which I did not look carefully, and finally achieved the algorithm complexity is O(n^3).
It takes O(n²) complexity to compare all the nodes in the two trees one by one. During the comparison process, it is found that the old node is not found in the new tree, so it needs to delete the old node. The time complexity of deleting a node in a tree (finding a suitable node to be placed at the deleted location) is O(n), and the time complexity of adding a new node is also O(n). Combined, the complexity of the two trees is O(n³).
Optimized Diff algorithm
The diff algorithm of the virtual DOM of Vue and React is roughly the same, and its core is based on two simple assumptions:
- Two identical components produce a similar DOM structure, and different components produce different DOM structures
- A group of nodes at the same level that can be distinguished by a unique ID
The (optimized) Diff three-point strategy:
- The movement of DOM nodes across hierarchies in the Web UI is minimal and can be ignored.
- Two components of the same type will generate similar tree structures, and two components of different types will generate different tree structures.
- For a set of self nodes at the same level, they can be distinguished by unique ids.
That is, comparisons are made only at the same level, not across levels
React optimizes Diff algorithm
React performs the following algorithm optimization based on the above optimized DIFF three-point strategy
- tree diff
- component diff
- element diff
tree diff
React performs a hierarchical comparison of tree algorithms. React uses updateDepth to level the Virtual Dom tree. Only nodes in the same color box are compared, that is, all children of the same parent node. If a node does not exist, both the node and its children are deleted. This is done by traversing the DOM tree once, completing the comparison of the entire DOM tree
Hierarchical comparison IMG
If it is a move across hierarchies, see figure
Operate img across hierarchies
When the root node finds that A has disappeared, it deletes A and its children. When A node A is found on D, A node (including its children) is created as A child node
Therefore, when moving across hierarchies, React does not simply move, but deletes and creates, which affects React performance. So try to avoid cross-level operations. (for example: controlling display to show and hide without actually adding and removing dom)
component diff
- If it is a component of the same type, compare it directly to the Virtual Dom Tree
- If the component is not of the same type, all the children of the component are directly replaced
- If the type is the same, but maybe the virtual DOM hasn’t changed, we can use shouldComponentUpdate() to determine if we need to diff
component vs img
If component D and component G, if the type is different but the structure is similar. In this case, react will delete D and create G because the type is different. So we can use shouldComponentUpdate() to return false without diff.
There is a new life cycle for Act15, 16
So: Component diff is optimized using shouldComponentUpdate()
element diff
Element Diff involves three operations: insert, move, and delete
Img without key
React compares the old set with the new set and finds that B in the new set is not equal to A in the old set, so A is deleted and B is created, and so on until D in the old set is deleted and C in the new set is created. =
React allows you to add keys to differentiate between these and render performance bottlenecks
Img using key
React first iterates through the new set, for(name in nextChildren), uses the unique key to determine whether the old set has the same node, if not, creates the node, if (preChild === nextChild) moves the node
Before moving, the position of the node in the new set will be compared with that in the old set lastIndex. If (child._mountIndex < lastIndex) moves the node, otherwise the move will not be carried out. This is a sequential movement optimization. Move only if the position in the new set is less than that in the old set.
If there is no node in the new set but in the old set during the traversal, the operation will be deleted
So: Element Diff is diff optimized with unique keys.
Summary: 1. Minimize cross-level operations in React. ShouldComponentUpdate () can be used to avoid repeating renders in React. 3. Add unique keys to reduce unnecessary rerendering
Vue optimization Diff
Vue2.0 adds the Virtual DOM and shares the same diff optimization principles as React
The difference is that diff calls the patch function to modify the real DOM just like patching
- patchVnode
- updateChildren
UpdateChildren is the core process of Vue DIff, which can be summarized as follows: oldCh and newCh each have two starting and ending variables, StartIdx and EndIdx. Their two variables are compared with each other in four ways. If none of the four comparisons match, if the key is set, the comparison will be performed with the key. During the comparison, the variable will be moved to the middle, and the comparison will end as soon as StartIdx>EndIdx indicates that at least one of oldCh and newCh has been traversed
Vue 2.x vs Vue 3.x
The core Diff algorithm of Vue2 adopts the algorithm of double-end comparison, which starts from the two ends of the old and new children, finds the reusable node with the help of key value, and then carries out relevant operations. Compared with the React Diff algorithm, it can reduce the number of nodes to be moved, reduce unnecessary performance loss, and be more elegant
Vue3. X draws on ivI algorithm and Inferno algorithm. The type of VNode is determined when VNode is created, and the bit operation is used to determine the type of a VNode in the process of mount/patch. On this basis, combined with the core Diff algorithm, the performance is improved compared with Vue2. The actual implementation can be combined with Vue3. X source code to see
The algorithm also uses the idea of dynamic programming to solve the longest recursive subsequence
Finally, I hope you can realize your dream as soon as possible!!
Welcome to exchange ~
- Wechat official account: Mr. Lian has cat disease
- Wechat id: Wanderlian
- Nuggets: Obsidian
- Personal blog: lianpf.github. IO /