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 sametypeandkeyAre 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