Skip to main content

Що таке "diffing algorithm"?

Diffing algorithm (алгоритм порівняння) - це серце механізму reconciliation у React. Він визначає, які саме частини віртуального дерева (Virtual DOM) змінилися між попереднім і новим станом інтерфейсу, щоб мінімально оновити реальний DOM.


Простіше кажучи

Коли React-компонент перерендерюється:

  1. React створює нове віртуальне дерево (Virtual DOM).
  2. Порівнює його з попереднім віртуальним деревом.
  3. Знаходить відмінності (diff) між ними.
  4. Застосовує лише змінені частини до реального DOM.

Алгоритм, який робить цей "розумний" крок порівняння, і називається diffing algorithm.


Навіщо він потрібен

Робота з DOM - дорога операція. Якби React просто заново пересоздавав усе дерево при кожній зміні, інтерфейс "гальмував" би навіть при найменших змінах.

Diffing algorithm дозволяє React:

  • зрозуміти, що саме змінилося;
  • оновити лише змінене місце;
  • зробити це максимально швидко й ефективно.

Як працює diffing у React (основні правила)

React використовує спрощений і оптимізований алгоритм diffing, заснований на двох ключових припущеннях:


1. Елементи різних типів → вважаються абсолютно різними

Якщо тип елемента змінився (<div><span> або ComponentAComponentB), React видаляє старий вузол і створює новий з нуля.

javascript
// Було <div>Hello</div> // Стало <span>Hello</span>

React повністю видалить <div> і створить новий <span>.


2. Елементи одного типу → React порівнює їхні атрибути (props)

React перевіряє, які пропси змінилися, і точково оновлює лише їх.

javascript
<button disabled={false}>Button</button> // → <button disabled={true}>Button</button>

React змінює лише атрибут disabled.


3. Списки елементів порівнюються за ключами (key)

Це - найважливіше правило для списків (.map()).

React порівнює елементи списку за їхніми ключами, щоб зрозуміти, які з них залишилися, видалилися або додалися.

javascript
{items.map(item => <li key={item.id}>{item.text}</li>)}

Якщо ключі:

  • однакові - React зберігає елемент (лише оновить його вміст);
  • різні - React видаляє старий елемент і створює новий.

Без ключів:

React думає, що елементи просто "зсунулися", і перемальовує весь список.

З ключами:

React "розуміє", що змінився лише один елемент, і оновлює лише його.


Приклад роботи diffing алгоритму

Було:

javascript
<ul> <li key="a">A</li> <li key="b">B</li> </ul>

Стало:

javascript
<ul> <li key="b">B</li> <li key="a">A</li> </ul>

Якщо немає ключів - React вирішить, що змінилися обидва елементи, і пересоздасть обидва <li>.

Якщо є ключі - React зрозуміє, що елементи просто помінялися місцями, і переставить їх, не пересоздаючи.


Час роботи алгоритму

Звичайне порівняння двох дерев вузол-за-вузлом - O(n³) (дуже повільно). React оптимізував це до O(n) завдяки ключам і спрощеним правилам:

  • не порівнює різні типи;
  • порівнює лише сусідні вузли;
  • використовує ключі для відстеження переміщень.

Diffing в рамках Fiber Architecture

З React 16+ diffing став інкрементальним і пріоритетним:

  • можна призупиняти diff для менш важливих компонентів;
  • можна відновлювати його пізніше (Concurrent Rendering);
  • можна призначати пріоритети оновленням (наприклад, введення тексту > анімації).

Підсумок

Що робить diffing algorithmНавіщо це потрібно
Порівнює старе і нове віртуальне деревоЩоб визначити, де змінився інтерфейс
Визначає мінімальні відмінності (diff)Щоб оновити DOM якомога менше
Використовує правила порівняння за типом і ключамиЩоб бути максимально швидким
Працює за O(n), а не O(n³)Щоб масштабуватися навіть на великих деревах
Є частиною reconciliationВходить у процес "узгодження" змін

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.