Як працює узгоджувач Fiber у React?

pic

React Fiber Reconciler

У цій статті я занурюся в світ React і розгляну, що є основною цінністю React, що таке механізм узгодження (Reconciler), як він працював до версії 16 і як працює зараз.

1- Що таке узгодження?

Перш за все, давайте з’ясуємо, що означає термін "узгодження". Згідно з перекладом, це означає:

“Дія узгодження одного погляду або переконання з іншим”

Це відображає основну мету самого React у створенні односторінкових додатків (Single-Page Applications).
Пам’ятаєте, як раніше, до появи односторінкових додатків (Single-Page Applications, SPAs), ми стикалися з проблемами через повільну маршрутизацію та те, як браузери обробляли переходи між сторінками? Щоб покращити швидкість переходів між сторінками в браузерах, React представив новий спосіб обробки маршрутизації у вебзастосунках, який отримав назву віртуальний DOM (Virtual DOM).

Замість використання нативної маршрутизації та навігації браузера, усі ці процеси були перенесені в пам’ять JavaScript. JavaScript почав обробляти сторінки та маршрутизацію, що значно підвищило швидкість роботи.

Для досягнення цієї мети команда React створила віртуальний DOM (Virtual DOM) і механізм узгодження стека (Stack Reconciler), які дозволяють обробляти дерево віртуального DOM у пам’яті, а потім застосовувати зміни до реального DOM декларативним способом.

2- Узгодження стека (Stack Reconciler) та історичний екскурс!

Добре, повернімося до попередніх років, до того, як були впроваджені React Hooks, і подивимося, як React створював дерева DOM на той час.
Нижче представлено зображення спрощеного робочого процесу React 15 та попередніх версій. У цих версіях використовувався узгоджувач стека (Stack Reconciler), який був структурою даних типу LIFO (Last In, First Out). Він відповідав за вибір роботи та повернення результатів, подібно до того, як працює стек викликів у JavaScript.

pic

Узгоджувач стека React до версії 16

Цей підхід вже був проривом, але він мав чимало проблем.
Головною проблемою узгоджувача стека (Stack Reconciler) було те, що він працював синхронно та послідовно. Це означало, що він не міг обробляти декілька одиниць роботи одночасно, ані в паралельному, ані в конкурентному режимі.

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

pic

Проблема нечутливого інтерфейсу користувача в узгоджувачі стека

Як видно, через синхронний та послідовний характер роботи узгоджувача стека, якщо користувач хоче ввести текст у текстове поле, відповідь системи буде повільною та нечутливою. Це відбувається, оскільки введення тексту є завданням високого пріоритету в порядку рендерингу, але немає способу вказати стеку обробити це завдання з вищим пріоритетом.
Ще однією проблемою було те, що якщо під час цього процесу виникала помилка, не було способу дізнатися, де саме вона сталася, і отримати стек викликів (Stack Trace). Це могло створювати серйозні труднощі.

Тепер уявіть велику програму з безліччю станів (States) та завдань, які потрібно обробляти — усе це могло перетворитися на хаос і знищити досвід користувача.

3- Fiber Reconciler — те, чого ми шукали!

У React, починаючи з версії 16, команда React представила новий підхід до обробки одиниць роботи та дерева віртуального DOM (Virtual DOM). Для вирішення двох основних викликів було створено механізм узгодження Fiber (Fiber Reconciler):

  1. Синхронна обробка одиниць роботи.
  2. Пріоритетність і конкурентність обробки одиниць роботи.

Сучасний узгоджувач Fiber (React Fiber Reconciler) складається з багатьох вузлів Fiber, які є простими об’єктами JavaScript із численними властивостями для обробки своєї роботи.

Fiber = { об’єкт JavaScript з багатьма властивостями АБО одиниця роботи }.

Fiber Reconciler = Поточний узгоджувач React, що базується на об’єктах Fiber або одиницях роботи.

Що таке одиниця роботи?

Одиницею роботи в React може бути зміна пропсів (Props), стану (State), оновлення DOM — усе, що може змінити результат для екрану.

Кожен Fiber має співвідношення 1 до 1 з чимось: чи то екземпляр компонента, чи то вузол DOM.
Тип чогось зберігається в полі "tag" об’єкта Fiber. Можливі типи виглядають так:

pic

Можливі типи "чогось" у співвідношенні 1 до 1 з об’єктом Fiber.

У вихідному коді бібліотеки React-DOM можна знайти функції з назвами на кшталт:

createFiberFromText();  
createFiberFromElement();  
createFiberFromPortal();

Це демонструє, що Fiber може створюватися на основі майже будь-яких опцій у DOM та екосистемі React.
Тепер давайте дізнаємося, як працює новий узгоджувач Fiber у React!

React є декларативним способом обробки маніпуляцій із DOM, тобто ми вказуємо, що хочемо бачити на екрані, а всю важку роботу React виконує «за лаштунками». Це дозволяє нам зосередитися на бізнес-логіці й інших важливих аспектах, необхідних для нашого проєкту.

Ось простий приклад сторінки:

pic

Приклад дерева DOM, яке ми хочемо побачити на екрані

Тепер подивімося, як це обробляється узгоджувачем Fiber у React:

pic

Процес узгодження в React Fiber у спрощеному вигляді

Як видно з наведеного зображення, узгоджувач Fiber у React створює дерево елементів DOM у пам’яті (Virtual DOM) і зберігає його як план реального DOM. Він працює над реальним DOM, оновлює Virtual DOM і застосовує ці зміни до реального DOM.

Цей процес має два етапи:

1- Фаза рендерингу (асинхронна)
2- Фаза коміту (синхронна)

Коли в застосунку відбувається оновлення, узгоджувач Fiber починає роботу з функції beginWork, яка приймає три параметри: поточне дерево в реальному DOM, дерево роботи в процесі (Work in Progress Tree) і лейни рендерингу (Rendering Lanes).

Процес значно складніший, але загальний огляд того, що відбувається «під капотом» в узгоджувачі React, можна показати на прикладі простого кліку на кнопку та зміни стану:

1- Коли користувач клацає на кнопку, процес починається викликом beginWork(currentTree, workInProgressTree, lanes). Ця функція рекурсивно перевіряє дерево зверху вниз, переходячи до вузлів-сусідів і дочірніх вузлів.

2- Якщо є робота, яку потрібно виконати (зміни в пропсах чи станах), вузли позначаються прапорцем «оновлено» (Updated Flag), що вказує на необхідність їхнього оновлення.
3- Коли завершено роботу над одиницею роботи Fiber, оновлення позначаються, і процес завершується викликом функції completeWork(currentTree, workInProgressTree, lanes), яка відповідає за підйом у робочому дереві.

4- Функція completeWork також створює дерево HTML-елементів, яке буде відображатися в реальному DOM на основі змін, зроблених у пам’яті за кадром.

5- Коли вся робота виконана і більше нічого не потрібно робити, Fiber завершує обробку й комітить усі новостворені DOM-дерева до реального DOM, щоб зміни стали видимими на екрані.

pic

Функція beginWork у бібліотеці React-DOM

pic

Функція completeWork у бібліотеці React-DOM

Фаза рендерингу та обробка дерева DOM у пам’яті виконуються повністю асинхронно та за кадром. Тому, якщо під час цього процесу виникає оновлення або переривання, процес може почекати, а іноді навіть припинитися (bail-out), щоб почати працювати над іншим завданням. Це дає змогу пріоритизувати, відкладати, скасовувати або виконувати кілька завдань одночасно в конкурентному режимі.
Це саме те рішення, яке ми шукали, щоб вирішити проблеми узгоджувача стека (Stack Reconciler), що були раніше.

Завдяки використанню узгоджувача Fiber (Fiber Reconciler) ми тепер маємо можливість виконувати конкурентне рендеринг (Concurrent Rendering), використовувати функції затримки (Suspense) та обробляти межі помилок (Error Boundaries), щоб уловлювати помилки під час фази рендерингу і показувати резервний інтерфейс користувачу без краху всього додатку!

Як працюють ефекти та застосовуються в цьому процесі?

Чудове питання! Результат дерева Fiber залежить не лише від нього самого. Ми також маємо список ефектів, які можуть відбутися, наприклад, мережевий запит, зміна в реальному DOM, виклик методів життєвого циклу (Lifecycle Methods) або будь-яка інша подія поза екосистемою React, яка потребує синхронізації зі станом React.

Під час фази коміту (Commit Phase) React проходить усі ефекти й застосовує їх до екземплярів компонентів. Результати стають видимими для користувача, і React виконує все це за один прохід.

pic

Побічні ефекти React у процесі узгодження

Ось і все! Хіба це не круто? Знання про те, що відбувається «під капотом», коли ви використовуєте React, дає вам змогу краще розуміти екосистему React і те, як вона обробляє процеси й керує DOM у фоновому режимі.

Сподіваюся, вам сподобалося. Якщо так, підписуйтесь на мене для майбутніх статей. Мир вам і вдалого кодування!

Ресурси:

https://www.youtube.com/watch?v=0ympFIwQFJw

https://www.youtube.com/watch?v=rKk4XJYzSQA&t=9s

https://www.youtube.com/watch?v=Zan16X8VvGM

Перекладено з: How does the React fiber reconciler work?

One comment on “Як працює узгоджувач Fiber у React?”

Leave a Reply

Your email address will not be published. Required fields are marked *