This article is from the study of the official website, if you have mastered the official website Diff students can skip.

Fiber architecture design power

We know React is going to have two trees. The two trees will alternate for UI rendering. The official website also provides the general generation process of the two trees.

  • At some point a node calls the Render () method of React, creating a tree of React elements.
  • On the next state or props update, the same render() method returns a different tree.
  • React needs to determine how to update the UI effectively based on the differences between the two trees to keep the current UI in sync with the latest tree.

React returns a new virtual DOM tree with render() in the update phase and an initial virtual DOM tree with render() in the initial mount phase. There’s going to be two trees.

How do you generate the minimum operand to convert one tree to another? Even in the most advanced algorithms, the complexity is O(n 3), where n represents the number of elements in the tree. If there are 1000 elements, the order of magnitude that needs to be calculated is 1 billion, which is not allowed. So React proposes a set of O(n) algorithms based on the following two assumptions:

  • Two elements of different types produce different trees;
  • Developers can use key prop to indicate which child elements are stable across different renders;

Through this design, the Diff algorithm is generated.

Diff

When comparing two trees, React first compares the root nodes of the two trees. Different types of root node elements have different shapes.

Compare different types of elements

When the root section is for a different type of element, React takes down the existing tree and builds a new one.

For example 🌰 : an entire build process is triggered when the element becomes .

When a tree is unmounted, the corresponding DOM node is also destroyed. The component instance will execute the componentWillUnmount() method.

When a new tree is created, the corresponding DOM node is created and inserted into the DOM. The component instance will execute the componentWillMount() method, followed by the componentDidMount() method. So the state associated with the previous tree is also cancelled.

An 🌰 :

<div>
  <Counter />
</div>

<span>
  <Counter />
</span>
Copy the code

The div element becomes the SPAN element, the Counter component is unloaded, and a new one is created.

Compare elements of the same type

When you compare two React elements of the same type, React preserves the DOM node and only compares the updated changed properties.

An 🌰 :

<div className="before" title="stuff" />

<div className="after" title="stuff" />
Copy the code

Comparing these two elements, React knows that it just changed the className attribute. Div elements are not unloaded and rebuilt.

Compare component elements of the same type

When a component is updated, the instance of the component remains the same, so that state remains consistent across different renderings.

React to update the component instance of props, to achieve consistent with the latest elements, and invoke the instance componentWillReceiveProps () and componentWillUpdate () method.

Next, the render() method is called, and the diff algorithm recurses over the previous result as well as the new one.

Recurse on the child nodes

By default, React iterates through lists of two child elements at the same time when iterating through the DOM node. When a difference occurs, a mutation is generated.

An 🌰 :

When new elements are added at the end of child elements, the change overhead is lower. Such as:

<ul>
  <li>first</li>
  <li>second</li>
</ul>

<ul>
  <li>first</li>
  <li>second</li>
  <li>third</li>
</ul>
Copy the code

React matches

  • first
  • , then matches the second< li>second tree, and finally inserts the third< li>third.

    If inserted at the head of the list can affect performance and be expensive. Such as:

    <ul>
      <li>Duke</li>
      <li>Villanova</li>
    </ul>
    
    <ul>
      <li>Connecticut</li>
      <li>Duke</li>
      <li>Villanova</li>
    </ul>
    Copy the code

    React will find that the new

  • Connecticut
  • child is different from the old

  • Duke
  • , and the result will be uninstalled and rebuilt. Compare this to mutate for each child element.

    Keys’ role in Diff

    To address the above mutate problem for each child element, React supports the key attribute. When a child element has a key, React uses the key to match the child element of the original tree with the child element of the latest tree.

    Look at this example:

    <ul>
      <li key="2015">Duke</li>
      <li key="2016">Villanova</li>
    </ul>
    
    <ul>
      <li key="2014">Connecticut</li>
      <li key="2015">Duke</li>
      <li key="2016">Villanova</li>
    </ul>
    Copy the code

    React now knows that

  • Connecticut
  • is new and the other two children have been moved.

    This is also why we don’t use index for our key, as it is possible to delete/add an element to the list, causing performance problems.

    conclusion

    • The architectural dynamics of Fiber’s design — the time complexity of the algorithm led to the need for optimization
    • Contrast the Diff algorithm with the DOM offload option of rebuilding.
    • Key impact on performance.