Skip to content

Instantly share code, notes, and snippets.

@SeLub
Created February 12, 2026 08:05
Show Gist options
  • Select an option

  • Save SeLub/fa0ba66213f93fee8b7fa3f1b950b741 to your computer and use it in GitHub Desktop.

Select an option

Save SeLub/fa0ba66213f93fee8b7fa3f1b950b741 to your computer and use it in GitHub Desktop.

Как работает алгоритм Fiber?

Алгоритм Fiber — это сердце архитектуры React (начиная с 16 версии). Если говорить просто, это полная переработка механизма рендеринга, которая превратила процесс обновления интерфейса из «непрерывного потока» в «умный планировщик».

Вот как это устроено «под капотом».


1. Зачем это было нужно?

До Fiber React использовал Stack Reconciler. Он работал синхронно: если у вас было огромное дерево компонентов, React начинал его обновлять и не останавливался, пока не закончит.

  • Проблема: Если обновление занимало 200 мс, браузер «зависал». Пользователь не мог кликнуть на кнопку или увидеть анимацию, потому что главный поток (Main Thread) был занят.

Fiber ввел инкрементальный рендеринг: возможность разбивать работу на части, приостанавливать её и возвращаться к ней позже.


2. Что такое "Fiber" как структура данных?

Fiber — это обычный JavaScript-объект, который соответствует компоненту. В отличие от старого подхода, где React просто вызывал функции компонентов, теперь он создает дерево «файберов».

Каждый Fiber-узел содержит:

  • State и Props: данные компонента.
  • Тип: (div, Button, и т.д.).
  • Ссылки: на родителя (return), первого ребенка (child) и соседний элемент (sibling).
  • Очередь обновлений: что именно нужно изменить.

3. Два этапа работы (Phases)

Алгоритм делит работу на два ключевых этапа:

Этап 1: Примирение (Reconciliation / Render Phase)

На этом этапе React строит новое дерево компонентов и определяет, что изменилось.

  • Асинхронность: Этот этап можно прервать. Если пришло высокоприоритетное событие (например, ввод текста пользователем), React поставит текущую сборку дерева на паузу, обработает ввод, а затем продолжит или начнет заново.
  • Результат: Формируется список изменений (эффектов).

Этап 2: Фиксация (Commit Phase)

Когда работа по сравнению закончена, React переходит к применению изменений в реальный DOM.

  • Синхронность: Этот этап нельзя прерывать. Он должен пройти быстро, чтобы пользователь увидел результат мгновенно и без визуальных артефактов.

4. Приоритезация задач

Fiber использует планировщик (Scheduler), который назначает задачам приоритеты:

  1. Immediate: (Синхронно) — например, ввод текста.
  2. User Blocking: — клики, анимации.
  3. Normal: — сетевые запросы, обработка данных.
  4. Low/Idle: — логирование, аналитика.

Пример: Если React занят отрисовкой тяжелого списка (Normal), но пользователь нажимает на кнопку (User Blocking), React «бросает» список, обрабатывает клик и только потом возвращается к списку.


5. Механизм Double Buffering (Двойная буферизация)

React Fiber использует технику из графики: у него всегда есть два дерева.

  • Current Tree: То, что сейчас отображено на экране.
  • Work-in-progress Tree: То, что React собирает в памяти прямо сейчас.

Как только "черновик" (work-in-progress) готов, React просто меняет указатель, и это дерево становится текущим. Это позволяет избежать ситуации, когда пользователь видит «наполовину обновленный» интерфейс.


Резюме: Fiber превратил React из "библиотеки для рендеринга" в эффективную "операционную систему для UI", которая умеет управлять временем и приоритетами.

Fiber-дерево — это не DOM-дерево. Более того, в современной архитектуре React понятие "Virtual DOM" стало более размытым, так как Fiber взял на себя его основные функции, но сделал их гораздо мощнее.

Давайте разложим всё по полочкам и найдем место Virtual DOM в этой цепочке.


1. Иерархия деревьев

Чтобы не запутаться, представьте три уровня структуры:

  1. React Elements: Это те самые объекты, которые возвращает JSX. Они очень легкие и "одноразовые". Каждый раз при рендеринге они создаются заново.
  2. Fiber Tree (и есть современный Virtual DOM): Это долгоживущие объекты. Они не пересоздаются при каждом чихе, а обновляются. Именно здесь хранится состояние (state) и хуки.
  3. Real DOM: Конечные узлы в браузере (<div>, <span>).

2. Так где же Virtual DOM?

Раньше (до Fiber) Virtual DOM был просто набором объектов, которые React сравнивал рекурсивно.

Сейчас Fiber-дерево — это и есть реализация Virtual DOM. Когда говорят "Virtual DOM" в контексте React 16+, обычно подразумевают процесс работы с Fiber-узлами.

Ключевое отличие:

  • Старый VDOM: Был просто "снимком" (snapshot) интерфейса. Сравнение шло по принципу «вот старый снимок, вот новый, найди 10 отличий».
  • Fiber: Это не просто снимок, а инфраструктура. Каждый Fiber-узел — это единица работы (unit of work). Он знает не только как выглядит элемент, но и когда его нужно обновить, какой у него приоритет и где находится его состояние.

3. Как они взаимодействуют? (Процесс)

Процесс обновления выглядит так:

  1. Событие: Вы вызываете setState.
  2. Планирование: React помечает Fiber-узел как требующий обновления и добавляет работу в очередь.
  3. Reconciliation (Сравнение): React идет по дереву Fiber-узлов. Он создает "черновое" дерево (work-in-progress), сравнивая новые React Elements (из JSX) со старыми Fiber-узлами.
  4. Diffing: Именно здесь происходит классический алгоритм сравнения (Diffing), который мы привыкли называть "магией Virtual DOM".
  5. Commit: Когда Fiber-дерево полностью готово и размечено (кому удалиться, кому добавиться), React одним махом переносит эти изменения в Real DOM.

4. Почему нельзя сразу работать с DOM?

Вы могли бы спросить: «Зачем нам Fiber, если можно сразу менять DOM?».

Проблема в том, что DOM очень медленный и "неуклюжий".

  • В DOM нельзя "поставить на паузу" создание узла.
  • В DOM нельзя легко рассчитать изменения в фоновом потоке.

Fiber-дерево выступает как "умная прослойка". Это песочница, в которой React может спокойно ошибаться, передумывать, сортировать задачи по важности и перестраивать структуру, не беспокоя браузер и не вызывая тормозов интерфейса.


Итог

Virtual DOM — это концепция. Fiber — это конкретная реализация этой концепции, которая превратила "простое сравнение объектов" в сложную систему управления задачами.

1. Есть ли цикл? Да, это Work Loop

Внутри React есть центральный цикл, который называется Work Loop.

В упрощенном виде он выглядит примерно так:

while (nextUnitOfWork !== null && !shouldYield()) {
  nextUnitOfWork = performUnitOfWork(nextUnitOfWork);
}
  • nextUnitOfWork: Это текущий Fiber-узел, который обрабатывает React.
  • shouldYield(): Это «предохранитель». React постоянно спрашивает у браузера: «У меня еще есть время в текущем кадре (16.6мс) или я уже начинаю тормозить интерфейс?». Если времени нет, цикл прерывается, React отдает управление браузеру (чтобы тот отрисовал анимации или обработал клики), а затем возвращается к работе.

React обходит дерево не рекурсивно (как раньше), а итеративно, используя связи child, sibling и return. Это превращает дерево в подобие связного списка, по которому можно гулять вперед-назад, останавливаясь в любой точке.


2. Commit: Переключение ссылки vs Обновление DOM

Здесь важно разделять состояние дерева в памяти и реальные узлы в браузере.

Когда работа над «черновиком» (Work-in-progress tree) закончена, происходит следующее:

Шаг А: Переключение ссылки (Pointer Swap)

React действительно просто переключает одну ссылку в корне приложения (hostRoot), чтобы current дерево теперь указывало на новое, только что собранное дерево.

  • Зачем: Это происходит мгновенно. Теперь React считает новое дерево «истинным» источником данных и состояния.

Шаг Б: Применение изменений к Real DOM (Mutation)

Но само по себе переключение ссылки в JavaScript-объектах не заставит браузер перерисовать кнопку или изменить текст. Real DOM — это внешнее API.

Во время этапа Reconciliation, обходя Fiber-узлы, React помечает их специальными флагами (эффектами):

  • Placement (нужно создать и вставить узел)
  • Update (нужно изменить атрибуты существующего узла)
  • Deletion (нужно удалить)

В фазе Commit React берет список этих эффектов и линейно (быстрым циклом) выполняет мутации в реальном DOM: document.appendChild(), node.textContent = ..., node.setAttribute().

Важно: Эти два шага происходят в рамках одной фазы Commit. Сначала подготавливается DOM (мутации), а затем переключается ссылка на дерево, чтобы методы жизненного цикла (или useEffect) видели уже обновленную картину.


Почему нельзя "просто переключить ссылку" на уровне DOM?

В браузере нет концепции «теневого DOM-дерева», которое можно мгновенно подменить одним движением (кроме технических нюансов типа DocumentFragment, но они не решают проблему глобально). DOM — это живая структура. Если вы хотите изменить <h1> на <h2>, вам в любом случае придется вызвать команду браузеру на удаление одного и создание другого.

Итого:

  1. Loop существует — он обрабатывает Fiber-узлы по одному, пока есть свободное время.
  2. Ссылка переключается, но только внутри React (между "текущим" и "завершенным" Fiber-деревом).
  3. Real DOM обновляется вручную через стандартные браузерные методы на основе меток, расставленных в Fiber-дереве.

Хотите узнать, как React понимает, что нужно прервать цикл (тот самый shouldYield), и как он использует MessageChannel для этого?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment