SoFunction
Updated on 2025-04-11

React Diffing Algorithm Complete Guide (Example Detailed Explanation)

The complete guide to React Diffing algorithms

1. Overview of Diffing Algorithm

1.1 What is Diffing

The Diffing algorithm is a algorithm used by React to compare the differences between two virtual DOM trees. It is used to determine the parts that need to be updated to minimize DOM operations.

1.2 Basic Principles

  • Different types of elements will produce different trees
  • Identify which child elements remain stable in different renderings through the key attribute
  • Adopt the same-level comparison strategy

2. Detailed explanation of Diffing strategy

2.1 Element type comparison

// Comparison of different types of elements// Old tree<div>
  <Counter />
</div>
// New Tree<span>
  <Counter />
</span>
// React Will completely delete the old tree,Rebuild a new tree

2.2 Comparison of elements of the same type

// Comparison of DOM elements of the same type// Old tree<div className="old" title="old">
  Hello
</div>
// New Tree<div className="new" title="new">
  World
</div>
// React Only change attributes will be updated

2.3 Component comparison

class MyComponent extends  {
  render() {
    // Only rendering results are compared when updated    return (
      <div>
        <h1>{}</h1>
        <p>{}</p>
      </div>
    );
  }
}

3. List Diffing

3.1 No key

// Low-efficient list renderingfunction ListWithoutKeys() {
  return (
    <ul>
      <li>Item 1</li>
      <li>Item 2</li>
      <li>Item 3</li>
    </ul>
  );
}
// When the list item changes,React Need to re-render all items

3.2 Optimization using key

// Rendering list using keyfunction ListWithKeys() {
  const items = [
    { id: 1, text: 'Item 1' },
    { id: 2, text: 'Item 2' },
    { id: 3, text: 'Item 3' }
  ];
  return (
    <ul>
      {(item => (
        <li key={}>{}</li>
      ))}
    </ul>
  );
}
// React Can be passed key Identify which elements remain the same

3.3 Best Practices for Keys

// Not recommended: Use index as keyconst BadList = () => (
  <ul>
    {((item, index) => (
      <li key={index}>{}</li>
    ))}
  </ul>
);
// Recommended: Use a stable unique identifier as keyconst GoodList = () => (
  <ul>
    {(item => (
      <li key={}>{}</li>
    ))}
  </ul>
);

4. Diffing algorithm implementation principle

4.1 Tree traversal strategy

function diffTree(oldTree, newTree) {
  if (oldTree === null) {
    // Insert a new node    return createNode(newTree);
  }
  if (newTree === null) {
    // Delete old nodes    return null;
  }
  if ( !== ) {
    // Replace node    return createNode(newTree);
  }
  // Update existing nodes  updateNode(oldTree, newTree);
  // Recursively process child nodes  diffChildren(, );
}

4.2 Sub-node comparison algorithm

function diffChildren(oldChildren, newChildren) {
  // The first round: processing updated nodes  for (let i = 0; i < (, ); i++) {
    diff(oldChildren[i], newChildren[i]);
  }
  // Handle new nodes  if ( > ) {
    ().forEach(child => {
      create(child);
    });
  }
  // Handle deleted nodes  if ( > ) {
    ().forEach(child => {
      remove(child);
    });
  }
}

5. Performance optimization strategy

5.1 Avoid unnecessary rendering

class OptimizedComponent extends  {
  shouldComponentUpdate(nextProps, nextState) {
    // Update only if necessary    return  !== ;
  }
  render() {
    return <div>{}</div>;
  }
}
// Use Optimize Function Componentsconst MemoizedComponent = (function MyComponent(props) {
  return <div>{}</div>;
});

5.2 List optimization

// Use key and memo to optimize list renderingconst OptimizedListItem = (({ item }) => (
  <li>{}</li>
));
function OptimizedList({ items }) {
  return (
    <ul>
      {(item => (
        <OptimizedListItem 
          key={} 
          item={item}
        />
      ))}
    </ul>
  );
}

5.3 Large list virtualization

import { FixedSizeList } from 'react-window';
function VirtualizedList({ items }) {
  const Row = ({ index, style }) => (
    <div style={style}>
      {items[index].text}
    </div>
  );
  return (
    <FixedSizeList
      height={400}
      width={300}
      itemCount={}
      itemSize={35}
    >
      {Row}
    </FixedSizeList>
  );
}

6. FAQs and Solutions

6.1 key related issues

// Problem: Re-rendering caused by key instabilityconst ProblematicList = () =&gt; (
  &lt;ul&gt;
    {((item, i) =&gt; (
      &lt;li key={()}&gt;{}&lt;/li&gt; // Don't do this    ))}
  &lt;/ul&gt;
);
// Solution: Use stable unique identifierconst FixedList = () =&gt; (
  &lt;ul&gt;
    {(item =&gt; (
      &lt;li key={}&gt;{}&lt;/li&gt;
    ))}
  &lt;/ul&gt;
);

6.2 Unnecessary re-rendering

// Problem: Parent component update causes unnecessary re-rendering of child componentsconst Parent = () =&gt; {
  const [count, setCount] = useState(0);
  return (
    &lt;div&gt;
      &lt;button onClick={() =&gt; setCount(count + 1)}&gt;
        Count: {count}
      &lt;/button&gt;
      &lt;Child data={data} /&gt; // Child will re-render even if data does not change    &lt;/div&gt;
  );
};
// Solution: Use useMemo orconst Parent = () =&gt; {
  const [count, setCount] = useState(0);
  const memoizedData = useMemo(() =&gt; data, [data]);
  return (
    &lt;div&gt;
      &lt;button onClick={() =&gt; setCount(count + 1)}&gt;
        Count: {count}
      &lt;/button&gt;
      &lt;Child data={memoizedData} /&gt;
    &lt;/div&gt;
  );
};

7. Summary

7.1 Key points of Diffing algorithm

  • Adopt the same-level comparison strategy
  • Different types of elements produce different trees
  • The importance of key attributes
  • Component stability

7.2 Optimization suggestions

  • Use keys reasonably
  • Avoid unnecessary nesting
  • Using immutable data structures
  • Use memo and useMemo appropriately
  • Large list consider virtualization

7.3 Best Practices

  • Keep the components pure
  • Reasonably split components
  • Use key correctly
  • Avoid deep component trees
  • Timely performance optimization

8. Classic interview questions

What is the function of the key in /vue? (What is the internal principle of key?)
2. Why is it better not to use index when traversing the list?
1. The role of key in virtual DOM:
Simply put: the key is the identifier of the virtual DOM object, and the key plays an extremely important role when updating the display.
To put it in detail: When the data in the state changes, react will generate [new virtual DOM] based on [new data], and then React compares the diff between [new virtual DOM] and [old virtual DOM]. The comparison rules are as follows:
a. The same key as the new virtual DOM was found in the old virtual DOM:
(1). If the content in the virtual DOM has not changed, use the previous real DOM directly
(2). If the content in the virtual DOM changes, a new real DOM is generated, and then the previous real DOM in the page is replaced.
b. The same key as the new virtual DOM is not found in the old virtual DOM. Create a new real DOM based on the data, and then render to the page
2. Problems that may be caused by using indexf as key:

1. If you perform destructive operations such as: reverse order addition, reverse order deletion, etc. on the data: unnecessary real DOM updates will be generated ==>The interface effect is no problem, but the effect is half low.
2. If the structure also contains the DOM of the input class: an error will be generated. There is a problem with the interface ==>.
3. Note! If there are no destructive operations such as reverse order addition and reverse order deletion of data, it is only used for rendering lists for display. There is no problem using index as key.

3. How to choose key in development?:

1. It is best to use the unique identifier of each piece of data as the key, such as the unique value of id, mobile phone number, ID number, student number, etc.
2. If you are sure that it is just a simple display of data, you can also use index.

This is all about this article about the complete guide to React Diffing algorithm. For more related React Diffing algorithm content, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!