Що таке "diffing algorithm"?
Diffing algorithm (алгоритм порівняння) - це серце механізму reconciliation у React. Він визначає, які саме частини віртуального дерева (Virtual DOM) змінилися між попереднім і новим станом інтерфейсу, щоб мінімально оновити реальний DOM.
Простіше кажучи
Коли React-компонент перерендерюється:
- React створює нове віртуальне дерево (Virtual DOM).
- Порівнює його з попереднім віртуальним деревом.
- Знаходить відмінності (diff) між ними.
- Застосовує лише змінені частини до реального DOM.
Алгоритм, який робить цей "розумний" крок порівняння, і називається diffing algorithm.
Навіщо він потрібен
Робота з DOM - дорога операція. Якби React просто заново пересоздавав усе дерево при кожній зміні, інтерфейс "гальмував" би навіть при найменших змінах.
Diffing algorithm дозволяє React:
- зрозуміти, що саме змінилося;
- оновити лише змінене місце;
- зробити це максимально швидко й ефективно.
Як працює diffing у React (основні правила)
React використовує спрощений і оптимізований алгоритм diffing, заснований на двох ключових припущеннях:
1. Елементи різних типів → вважаються абсолютно різними
Якщо тип елемента змінився (<div> → <span> або ComponentA → ComponentB),
React видаляє старий вузол і створює новий з нуля.
// Було
<div>Hello</div>
// Стало
<span>Hello</span>React повністю видалить <div> і створить новий <span>.
2. Елементи одного типу → React порівнює їхні атрибути (props)
React перевіряє, які пропси змінилися, і точково оновлює лише їх.
<button disabled={false}>Button</button>
// →
<button disabled={true}>Button</button>React змінює лише атрибут disabled.
3. Списки елементів порівнюються за ключами (key)
Це - найважливіше правило для списків (.map()).
React порівнює елементи списку за їхніми ключами, щоб зрозуміти, які з них залишилися, видалилися або додалися.
{items.map(item => <li key={item.id}>{item.text}</li>)}Якщо ключі:
- однакові - React зберігає елемент (лише оновить його вміст);
- різні - React видаляє старий елемент і створює новий.
Без ключів:
React думає, що елементи просто "зсунулися", і перемальовує весь список.
З ключами:
React "розуміє", що змінився лише один елемент, і оновлює лише його.
Приклад роботи diffing алгоритму
Було:
<ul>
<li key="a">A</li>
<li key="b">B</li>
</ul>Стало:
<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 | Входить у процес "узгодження" змін |
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.