Как работает Fiber-архитектура в React?

SeniorReact · Frontend·Обновлено 25 августа 2026
Коротко
Fiber — это переписанный реконсилер React, представляющий дерево компонентов как связный список fiber-узлов, что позволяет разбивать рендер на прерываемые единицы работы, приоритизировать обновления и приостанавливать/возобновлять их до синхронной фазы коммита в DOM.

Суть проблемы, которую решает Fiber

До React 16 согласование (reconciliation) выполнялось по алгоритму Stack Reconciler: обход дерева компонентов был рекурсивным и синхронным, без возможности прерваться. При большом дереве это блокировало поток JS на всё время обновления, вызывая просадки FPS и залипание UI при вводе.

Fiber — это переписанный реконсилер, превращающий рекурсивный обход в дерево связанных объектов (fiber-узлов) и итеративный цикл работы, который можно приостанавливать, возобновлять, распределять по приоритетам и даже отбрасывать.

Структура fiber-узла

Каждый компонент/элемент представлен fiber-объектом с полями:

  • type, key — что рендерим
  • child, sibling, return — связи как в связном списке/дереве, заменяющие рекурсию обходом по ссылкам
  • pendingProps / memoizedProps — новые и уже отрисованные пропсы
  • alternate — ссылка на fiber из другого дерева (double buffering)
  • flags — side-effect теги: Placement, Update, Deletion и т.д.
  • lanes — приоритет обновления

Double buffering: current и work-in-progress

React держит два дерева файберов: current (то, что уже отрисовано на экране) и workInProgress (строящееся обновление). Они связаны через alternate. Когда работа над WIP-деревом завершена и закоммичена, WIP становится новым current, а старое дерево переиспользуется под следующее обновление — это экономит аллокации.

Две фазы: render и commit

  1. Render/Reconciliation — обход дерева функциями beginWork/completeWork: вычисление нового состояния, сравнение с предыдущим деревом, простановка flags. Фаза прерываемая: React может остановиться после обработки очередного fiber-узла, отдать управление браузеру (например, для обработки инпута), а потом продолжить с того же места.
  2. Commit — применение накопленных side-effects к реальному DOM. Эта фаза всегда синхронная и непрерываемая, чтобы пользователь не увидел промежуточное состояние интерфейса.

Кооперативный планировщик и приоритеты

Прерываемость реализована через scheduler: работа режется на units of work — по одному fiber-узлу за раз. После каждого узла React проверяет через shouldYield, остался ли лимит времени в текущем кадре (около 5 мс). Если лимит исчерпан, управление отдаётся браузеру. Обновления имеют разные приоритеты (lanes): пользовательский ввод обрабатывается синхронно, а transitions и фоновая работа — с более низким приоритетом и могут быть прерваны более срочным обновлением.

Что это даёт

Fiber — фундамент конкурентных возможностей React: startTransition, useDeferredValue, Suspense, стриминговый SSR. Без возможности прерывать и приоритизировать рендер эти механизмы были бы невозможны.

Что хочет услышать интервьюер

Понимание, что Fiber — это структура данных плюс алгоритм обхода, а не просто «новый рендерер»

Знание, что render-фаза прерываема, а commit-фаза всегда синхронна

Понимание double buffering — пары current/workInProgress через alternate

Знание про lanes/приоритеты и их связь с concurrent-фичами (transitions, Suspense)

Умение отличить beginWork/completeWork (render) от применения side-effects (commit)

Пример: Упрощённая структура fiber-узла

type Fiber = {
  type: any;              // компонент или тег DOM-элемента
  key: string | null;

  // связи дерева вместо рекурсии
  child: Fiber | null;
  sibling: Fiber | null;
  return: Fiber | null;   // родитель

  pendingProps: any;      // новые пропсы для этого рендера
  memoizedProps: any;     // пропсы, уже отрисованные ранее
  memoizedState: any;     // состояние хуков/класса

  alternate: Fiber | null; // связь с fiber-ом из другого дерева
  flags: number;           // side-effect теги: Placement, Update, Deletion
  lanes: number;           // приоритет обновления
};

Пример: Упрощённый кооперативный цикл работы

let workInProgress: Fiber | null = null;

function workLoopConcurrent() {
  // обрабатываем по одному fiber-узлу, пока есть время в кадре
  while (workInProgress !== null && !shouldYield()) {
    workInProgress = performUnitOfWork(workInProgress);
  }
}

function performUnitOfWork(unitOfWork: Fiber): Fiber | null {
  // спускаемся вглубь дерева, создавая дочерние fiber-узлы
  const next = beginWork(unitOfWork);

  if (next === null) {
    // дошли до листа — поднимаемся обратно и завершаем узлы
    completeUnitOfWork(unitOfWork);
  }

  return next;
}

// если время кадра вышло — React отдаёт управление браузеру
// и продолжит с сохранённого workInProgress на следующем тике

Типичные ошибки

Путают Fiber с виртуальным DOM в целом, будто это одна и та же концепция

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

Не могут объяснить, зачем нужны два дерева (current и work-in-progress)

Не знают про lanes и приоритеты, думают, что прерывание работает только по таймеру

Описывают устаревший effect list из ранних версий React 16 вместо актуального обхода по flags

Лучшие курсы по теме

изображение курса

TypeScript с нуля

Антон Ларичев
AI-тренажерыAI-тренажеры
Практика в студииПрактика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.8
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

Feature-Sliced Design

Антон Ларичев
AI-тренажерыAI-тренажеры
Практика в студииПрактика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.5
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

Next.js - с нуля

Антон Ларичев
AI-тренажерыAI-тренажеры
Практика в студииПрактика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.7
3 999 ₽ 6 990 ₽
Подробнее