Урок по треку React Native 8 мин

Как устроен React Native: мост, JSI, Fabric, TurboModules

Потоки, старый мост, JSI, Fabric, TurboModules, Codegen и Hermes.

React Native рендерит настоящие нативные компоненты: <View> становится UIView на iOS и android.view.View на Android. Ваш код на JavaScript описывает интерфейс, а платформа его рисует. Вопрос «как JS общается с нативом» задают почти на каждом собесе middle и выше, и ответ изменился с приходом новой архитектуры.

Потоки

  • JS-поток: выполняет ваш код, React, обработчики событий.
  • UI (main) поток: нативный интерфейс, жесты, отрисовка. Блокировать его нельзя.
  • Фоновый поток раскладки: Yoga считает Flexbox-раскладку.

Если JS-поток занят тяжёлым вычислением, нажатия перестают обрабатываться, анимации на JS замирают. Если занят UI-поток, тормозит вообще всё.

Старая архитектура: мост

Раньше JS и натив общались через мост (bridge): сообщения сериализовались в JSON, складывались в пакеты и асинхронно передавались на другую сторону. Последствия:

  • всё асинхронно, синхронно спросить натив нельзя;
  • сериализация больших данных дорогая;
  • мост становится узким местом при частых событиях (прокрутка, жесты);
  • все нативные модули инициализировались при старте, даже ненужные.

Новая архитектура

Состоит из нескольких частей, которые работают вместе.

JSI (JavaScript Interface). C++ API, через который движок JS напрямую вызывает функции C++ и держит ссылки на нативные объекты. Нет JSON и обязательной асинхронности: вызов может быть синхронным. На JSI построено всё остальное.

TurboModules. Нативные модули нового поколения. Загружаются лениво, при первом обращении, а не на старте. Вызываются через JSI. Интерфейс модуля описывается спецификацией на TypeScript.

Codegen. По спецификациям на TypeScript (или Flow) генерирует C++ и нативный код-склейку. Типы JS и натива проверяются при сборке, а не падают в рантайме.

Fabric. Новая система рендеринга. Дерево теней (shadow tree) живёт в C++ и общее для платформ, раскладка может выполняться синхронно, а рендерер поддерживает конкурентные возможности React 18+: useTransition, автоматическое объединение обновлений, корректный useLayoutEffect с синхронным чтением размеров.

Bridgeless. Режим без моста: всё общение идёт через JSI.

Новая архитектура включена по умолчанию с React Native 0.76, а с 0.82 старую архитектуру отключить уже нельзя. Старые библиотеки часто работают через слой совместимости (interop layer), но при выборе зависимостей стоит проверять поддержку новой архитектуры.

Hermes

Движок JavaScript от Meta, оптимизированный для мобильных устройств и используемый по умолчанию. Главная особенность: JS компилируется в байткод на этапе сборки, а не разбирается при запуске. Отсюда быстрее старт (TTI) и меньше потребление памяти. Отладка через React Native DevTools, профилирование через встроенный профайлер Hermes.

Как это объяснить на собесе

Короткая версия: «Раньше JS и натив переписывались асинхронными JSON-сообщениями через мост. Теперь JS через JSI вызывает C++ напрямую, модули грузятся лениво и типизированы через Codegen, а Fabric рендерит через общее C++-дерево и поддерживает конкурентный React».

Частые ошибки

  • Говорить, что React Native рисует в WebView. Нет, компоненты нативные.
  • Считать, что JSI делает всё синхронным. Он даёт возможность, но долгие операции по-прежнему должны быть асинхронными, иначе заблокируют поток.
  • Путать Hermes с новой архитектурой. Это разные вещи: движок JS и способ общения с нативом.

Что спросят на собесе

  • Какие потоки есть в приложении и что будет, если заблокировать каждый.
  • Чем плох мост и что его заменило.
  • Что такое JSI, Fabric, TurboModules, Codegen.
  • Зачем Hermes и что даёт компиляция в байткод.
  • Что нужно проверить в зависимостях при переходе на новую архитектуру.

Закрепите за 5 минут

После урока в тренажёре 3-5 проверочных вопросов, дальше модуль уходит в повторения.