Перейти к содержанию
Innovialabs

Новая архитектура React Native: Fabric, TurboModules и JSI

Продвинутое3 мин

Коротко

Новая архитектура заменяет асинхронный bridge с JSON-сериализацией прямыми вызовами через JSI: нативные модули грузятся лениво и типизируются через Codegen, а рендерер Fabric поддерживает конкурентные возможности React. Миграция начинается с аудита зависимостей.

Что изменилось и зачем

В старой архитектуре JavaScript и нативный код общались через bridge: каждое сообщение сериализовалось в JSON, складывалось в очередь и передавалось асинхронно. Это работало, но имело ограничения:

  • накладные расходы на сериализацию при частом обмене данными;
  • все вызовы асинхронные — нельзя синхронно спросить что-то у нативной стороны;
  • все нативные модули инициализировались при старте, даже если не нужны;
  • рендерер не умел работать с конкурентными возможностями React.

Новая архитектура состоит из трёх частей, которые снимают эти ограничения.

Три составляющие

JSI (JavaScript Interface) — C++ API, через который JavaScript-движок держит прямые ссылки на нативные объекты и вызывает их методы. Без JSON и без очереди. Вызовы могут быть синхронными, когда это оправдано.

TurboModules — новая система нативных модулей поверх JSI:

  • модули загружаются лениво, при первом обращении;
  • интерфейс описывается в TypeScript или Flow, а Codegen генерирует нативные заготовки — несоответствие типов ловится на сборке, а не в рантайме.

Fabric — новый рендерер, ядро которого написано на C++ и общее для iOS и Android. Он умеет синхронно измерять и обновлять разметку и поддерживает конкурентный рендеринг React: Suspense, transitions, корректный useLayoutEffect.

Вместе с ними пришёл bridgeless-режим, в котором старый bridge не создаётся вовсе. В свежих версиях React Native новая архитектура включена по умолчанию, а старая постепенно выводится из поддержки.

Где ощущается выигрыш

Конкретные цифры зависят от приложения, поэтому смотрите на механизмы:

  • Старт приложения — модули не инициализируются все сразу.
  • Частый обмен данными с нативом (жесты, анимации, сенсоры, работа с файлами) — нет затрат на сериализацию.
  • Отзывчивость интерфейса — срочные обновления не ждут тяжёлого рендера благодаря конкурентным возможностям.
  • Синхронные операции вроде измерения элемента перед показом подсказки — без мерцания.

Если приложение в основном показывает списки из API, разница может быть незаметной. Проверяйте профилированием на реальных устройствах и release-сборках.

Как выглядит модуль с Codegen

Спецификация TurboModule на TypeScript:

// specs/NativeDeviceInfo.ts
import type { TurboModule } from "react-native";
import { TurboModuleRegistry } from "react-native";

export interface Spec extends TurboModule {
  getDeviceName(): string;
  getBatteryLevel(): Promise<number>;
}

export default TurboModuleRegistry.getEnforcing<Spec>("DeviceInfo");

Codegen подключается в package.json:

"codegenConfig": {
  "name": "AppSpecs",
  "type": "modules",
  "jsSrcsDir": "specs",
  "android": { "javaPackageName": "com.example.app" }
}

После этого нативную реализацию пишут на Kotlin/Java и Objective-C++/Swift по сгенерированным интерфейсам.

Шаги миграции существующего приложения

  1. Аудит зависимостей. Составьте список всех библиотек с нативным кодом и проверьте их статус в React Native Directory или в репозиториях.
  2. Обновление React Native до актуальной версии. Делайте это по шагам и сверяйтесь с Upgrade Helper — прыжок через много версий сразу усложняет поиск проблем.
  3. Включение архитектуры, если в вашей версии она ещё не включена по умолчанию: newArchEnabled=true в android/gradle.properties, для iOS — переустановка pods с новой архитектурой; в Expo — соответствующий флаг в конфиге приложения.
  4. Перенос собственных модулей на TurboModules и собственных нативных компонентов на Fabric: спецификация, Codegen, реализация.
  5. Тестирование обеих платформ в release-режиме: навигация, жесты, клавиатура, модальные окна, сторонние SDK.
  6. Поэтапный выпуск — staged rollout в сторах и мониторинг крашей.

Совместимость библиотек

Это главный риск миграции.

  • Interop-слой позволяет многим старым модулям и компонентам работать без переписывания, но не всем и не всегда идеально.
  • Ломаются чаще всего библиотеки, которые напрямую обращаются к объекту bridge, используют setNativeProps или нестандартные приёмы работы с UIManager.
  • Заброшенные библиотеки — повод заменить их на поддерживаемые аналоги, сделать форк или написать небольшой модуль самостоятельно.
  • Обновляйте библиотеки до версий с явной поддержкой новой архитектуры до переключения, а не после.

Частые вопросы

Если приложение стабильно работает, срочности нет, но откладывать надолго рискованно: новые версии React Native и библиотек ориентируются на новую архитектуру, а старая уходит из поддержки.

Поможем с этим

Если хотите не разбираться самим, а получить результат — этим мы занимаемся каждый день.

Обсудить проект

Читайте также

Есть идея или задача? Расскажите нам

Ответим в течение рабочего дня и предложим решение. Консультация бесплатная.