30 марта 2022 года команда инженеров Meta анонсировали новую версию React Native 0.68. Помимо различных минорных улучшений и фиксов эта версия содержит историческое для платформы изменение, впервые мы можем попробовать в своих приложениях так называемую новую архитектуру. Давайте вместе разберемся что за новая архитектура и почему к ней шли без малого 4 года.
Как устроен React Native
React Native это набор инструментов, библиотек и компонентов которые позволяют разработчику создавать приложения с нативным интерфейсом и логикой запущенной на JS движке.
За сборку приложения отвечают следующие модули:
BUCK - мультиплатформенная система сборки
Metro bundler - сборщик JS написаный специально для React Native
React Native CLI - набор утилит для сборки приложения под конкретную платформу
Во время выполнения обязательными являются:
Yoga layout - кросс платформенный менеджер компоновки с синтаксисом близки к css flex box
ReactJS и React Native - ядро приложения, отвечают за рендеринг на стороне JS и взаимодействие с нативным слоем
И так мы собрали RN приложение. Что же происходит под капотом?
Пользователь нажимает на иконку приложения
Native Thread загружаешь все нативные зависимости и модули
Native Thread стартует JS Thread который загружает собраный js bundle
JS Thread посылает сериализованное сообщение через Bridge о том как отрисовать UI на нативной стороне.
Shadow Thread получает эти сообщения и формирует UI Tree
На базе UI Tree менеджер компоновки Yoga формирует нативные компоненты с размерами для конкретной платформы и устройства и передает на отрисовку в Native Thread
Native Thread отрисовывает компоненты на экране. Ниже приведен пример мэпинга RN компонентов на компоненты специфичные различным платформам
Взаимодействие с пользователем происходит по такой же схеме, Native Thread отвечает за обработку жестов и отправляет информацию о событии через Bridge на JS Thread где происходит расчет нового состояния UI и повторяются шаги 4-7.
Проблемы старой архитектуры
В 2018 году команда RN объявила о начале большой работы по созданию новой архитектуры. Основной проблемой виделся асинхронный Bridge
большое количество событий проходящих через Bridge и требующих сериализации/десериализации может послужить бутылочным горлышком и вызывать медлительность UI
асинхронная природа Bridge не позволяет использовать его с синхронными нативными компонентами эффективно
так как коммуникация между Native и JS происходит через сообщение, JS не может эффективно управлять Shadow Thread напрямую так как Shadow Thread ничего не знает о структурах данных на стороне JS
Новая архитектура
Схематично новая архитектура выглядит так
Вы наверное заметили множество новых названий, давайте рассмотрим каждое из них.
JSI - JavaScript Interface замена для Bridge. С помощью JSI можно напрямую взаимодействовать с нативными модулями избегая накладных расходов на пересылку сообщений. Через JSI нативные методы будут доступны для JavaScript через хост-объекты C++. Эти хост объекты могут содержать как самостоятельную функциональность на C++ так и выступать посредниками для взаимодействия с нативной платформой, например на Objective-c или Java через JNI. Важно что методы JSI могут быть как синхронными так и асинхронными.
Fabric - новая система рендеринга пришедшая на замену UIManager. Благодаря JSI теперь не нужно держать копию дерева компонентов на JS и Shadow thread и синхронизировать ее через Bridge а можно манипулировать этим деревом напрямую. Fabric делает работу с UI синхронной а так же приоритизирует UI задачи над асинхронными вызовами, например HTTP запросы или IO операции.
Turbo Modules - в текущей архитектуре все модули для работы с нативной функциональностью (Bluetooth, Geo, Camera и т.д.) должны быть загружены во время старта приложения. На практике это значительно замедляет время старта приложения. Turbo Modules устраняют эту проблему и позволяют загружать нативные модули тогда когда они нужны в приложении. Еще одним преимуществом является использование JSI для коммуникации между модулем и JS.
CodeGen - упрощает создание нативных интерфейсов для работы с Turbo Modules и Fabric. С помощью Flow или TypeScript разработчик модуля описывает его интерфейс а С++ код будет сгенерирован автоматически.
Теперь в новой схеме JS Thread намного сильнее интегрирован в разные процессы напрямую, можно параллельно общаться с несколькими модулями не дожидаясь ответа в виде сообщения через Bridge как было раньше.
Более детально почитать про то как работает новый рендеринг можно на сайте React Native в специальном разделе.
Как использовать на практике?
На практике для поддержки новой архитектуры мы должны обеспечить работоспособность всех нативных модулей.
Внутри React Native все компоненты уже поддерживают новую архитектуру и если вы собираетесь создать новое приложение или же просто хотите экспериментировать с новой архитектурой то эта инструкция будет полезна.
Если вы являетесь разработчиком RN библиотек или у вас есть свои нативные модули то следуя этой инструкции вы сможете адаптировать свою библиотеку. Хорошим примером реализации новой архитектуры могут служить следующие библиотеки:
react-native-screens - с обзором pull requests которые были сделаны для поддержки новой архитектуры
react-native-mmkv - использует JSI для быстрого доступа к MMKV хранилищу написанному на С++
React Native New Architecture Sample - репозиторий с пошаговым объяснением как мигрировать вашу библиотеку на новую архитектуру
А что с уже существующими приложениями? По моим ощущениям потребуется еще от 6 до 12 месяцев для того чтобы разработчики библиотек адаптировали их под новую архитектуру. Однозначно можно сказать одно - новая архитектура эта та реальность в которой мы уже находимся. Не игнорируйте ее, помогайте сообществу, экспериментируйте и это положительно скажется как на вашем проекте так и на вашем опыте работы с React Native.
Полезные материалы
Официальная рабочая группа по миграции на новую архитектуру
Обсуждения в репозитории react-native-proposals
серия видео от Oscar Franco где он разрабатывает JSI модуль
Также подписывайтесь на мой Телеграм-канал React Native World — там я размещаю последние новости, обзоры и статьи из мира React Native.