The DOM-diff algorithm in Act17
The DOM-diff in Act17 is the process of generating a new Fiber tree by comparing the old fiber tree to the new JSX
- Single node comparison
- Multinode comparison
1. Compare single nodes
If the new child node (JSX) has only one element, the old fiber can be one or more
- If the two nodes are the same
type
andkey
Are the same - Insert:
Placement=2
- Update:
Update=4
- Insert and update:
PlacementAndUpdate=6
- Delete:
Deletion=8
1.1. One-to-one, different types
/ / the old<div>
<h1>h1</h1>
</div>/ / new<div>
<h2>h1</h2>
</div>
Copy the code
- 1. Mark this old fiber as deleted during the reconciliation phase
- 2. Generate new Fiber nodes according to the new JSX and mark them as inserts
- 3. Delete H1 and add H2 in the submission phase
1.2. One-to-one, different keys
/ / the old<div>
<h1 key='h1'>h1</h1>
</div>/ / new<div>
<h1 key='h2'>h1</h1>
</div>
Copy the code
- 1. Mark this old fiber as deleted during the reconciliation phase
- 2. Generate new Fiber nodes according to the new JSX and mark them as inserts
- 3. Delete H1 and add H2 in the submission phase
1.3. One-to-one, type&key is the same
/ / the old<div>
<h1 key='h1'>h1</h1>
</div>/ / new<div>
<h1 key='h1'>h2</h1>
</div>
Copy the code
- 1. Mark the old fiber as updated during the reconciliation phase, and update the new properties to the old fiber
- 2. Update during commit phase
1.4. A couple more
/ / the old<div>
<h1 key="h1">h1</h1>
<h2 key="h2">h2</h2>
</div>/ / new<div>
<h2 key="h2">h2</h2>
</div>
Copy the code
- Mark h1 for deletion
- Mark H2 as updated
- Commit phase to delete, update
2. Multiple nodes
- Multiple nodes go through two rounds of traversal
- The first round of traversal mainly deals with the update tags of nodes, including the update of attributes and types
- The second round of traversal deals with adding, deleting, and moving tokens of nodes
- The movement is followed by as little movement as possible, with the new high status motionless and the low status moving
2.1. One-to-one comparison, all reusable
/ / the old<ul>
<li key="A">A</li>
<li key="B">B</li>
<li key="C">C</li>
<li key="D">D</li>
</ul>/ / new<ul>
<li key="A">A-new</li>
<li key="B">B-new</li>
<li key="C">C-new</li>
<li key="D">D-new</li>
</ul>
Copy the code
- One by one, all marked as updated
2.2. One by one comparison, with the same key but different type
/ / the old<ul>
<li key="A">A</li>
<li key="B">B</li>
<li key="C">C</li>
<li key="D">D</li>
</ul>/ / new<ul>
<div key="A">A-new</div>
<li key="B">B-new</li>
<li key="C">C-new</li>
<li key="D">D-new</li>
</ul>
Copy the code
- In the first round of comparison, the key=’A’ is the same, but the type is different. The old fiber is marked as deleted, and the new fiber node is generated according to the new JSX
- Enter the second loop, map the type and key of the old fiber into a map={B:’li’,C:’li’,D:’li}, loop over and mark the remaining old fibers as updates
2.3. Many-to-many, out of order
/ / the old<ul>
<li key="A">A</li>
<li key="B">B</li>
<li key="C">C</li>
<li key="D">D</li>
<li key="E">E</li>
<li key="F">F</li>
</ul>/ / new<ul>
<li key="A">A-new</li>
<li key="C">C-new</li>
<li key="E">E-new</li>
<li key="B">B-new</li>
<li key="G">G</li>
</ul>
Copy the code
- For the first round of comparison, fiber A is marked as updated
- Enter the second cycle, map the type and key of the old fiber into a map={B:’li’,C:’li’,D:’li’,E:’li’,F:’li ‘}, loop over, and mark can be reused, deleted, and moved