Нітро-модулі: чому статичні прив’язки перевершують React Native TurboModules
Пояснює, як Nitro Modules використовують заздалегідь скомпільовані статичні зв’язки замість динамічних пошуків, що дозволяє їм значно перевершувати TurboModules та Expo Modules у React Native.
TurboModules мали стати рішенням проблеми. Вони замінили застарілу архітектуру моста, усунули зайвий навантаження та стали загальноприйнятим підходом для написання нативного коду, який взаємодіє з JavaScript. Потім з’явилась новіша бібліотека під назвою Nitro Modules, яка зробила це „останнє рішення“ застарілим.
Опубліковані тестування показують, що при тестуванні ідентичних синхронних викликів функцій Nitro Modules можуть перевершувати Expo Modules у понад 59 разів, а TurboModules — приблизно у 15 разів. Навіть коли йдеться про рядки, які зазвичай додають навантаження під час обробки між JavaScript та нативним кодом, Nitro все одно має перевагу у 5–13 разів. При передачі більших об’ємів даних, таких як зображення чи необроблені буфери, Nitro досягає ще одного покращення на 8–40 відсотків, завдяки підходу без копіювання, який уникає дублювання даних у пам’яті.
Такі цифри вимагають пояснення. Що саме робить Nitro внутрішньо, і чому цей підхід не з’явився раніше?
Проблема, яку ніхто інший не вирішив
Nitro не був створений як інструмент для тестування продуктивності. Він виник у результаті роботи Marc Rousavy, творця VisionCamera, у відповідь на дуже конкретну проблему: ані TurboModules, ані Expo Modules не могли належним чином підтримувати обробку кадрів.
У VisionCamera один кадр камери можна уявити як буфер об’ємом приблизно 10 мегабайт. Цей буфер не можна скопіювати через місткування, навіть за допомогою TurboModules, і він також не поміщається у звичайну структуру, схожу на JSON. Насправді Rousavy потребував способу передати до JavaScript прямо складний, зі станом нативний об’єкт, написаний на C++ чи Swift, разом із функціями та властивостями. У TurboModules не було механізму для такого типу об’єктів.
Отже, Nitro був створений саме для того, щоб це зробити можливим, а значні покращення швидкості виявилися додатковою перевагою, яка привернула набагато більше уваги, ніж первинна проблема, яку він вирішував.
Одне архітектурне рішення
Справжня різниця між TurboModules та Nitro зводиться до одного дизайнерського рішення: як кожна система представляє нативний об’єкт після того, як він потрапляє до двигуна JavaScript.
TurboModules ґрунтуються на jsi::HostObject. Кожного разу, коли код JavaScript отримує доступ до властивості чи викликає метод одного з цих об’єктів, движок мусить динамічно та миттєво вирішувати цей запит. Це пошук відбувається при кожному виклику, і ця постійна витрата швидко накопичується для модулів, які викликаються часто.
Nitro обирає інший підхід, використовуючи jsi::NativeState. У поєднанні з інструментом генерації коду під назвою Nitrogen він заздалегідь створює всі необхідні біндинги для C++, Swift чи Kotlin ще до запуску додатка. Нічого не вирішується динамічно під час виконання. Перетворення між JavaScript та нативними типами компілюється статично заздалегідь, тож виклик модуля Nitro більше нагадує виклик звичайної функції, ніж використання механізму динамічного пошуку під час виконання.
Саме ця зміна — попередньо скомпільовані статичні біндинги замість динамічних пошуків під час виконання — пояснює більшу частину різниці в продуктивності, яка спостерігається у тестах.
У Nitro будь-який нативний об’єкт, створений на C++, Swift чи Kotlin, називається гібридним об’єктом. Nitrogen аналізує визначення інтерфейсу TypeScript та автоматично генерує код, необхідний для переміщення цього об’єкта через межу між JS та нативними середовищами, включаючи обробку енумерацій, союзів та структур. Саме цей інструментарій дозволив Rousavy використовувати щось настільки нетрадиційне, як кадр від живої камери, без необхідності вручну писати окремий код-мост для кожної з трьох платформ.
Чому це виходить за межі простої бібліотеки
VisionCamera став початковим доказом того, що цей підхід ефективний, але конструкція Nitro ніколи не була призначена як одноразове рішення для окремого випадку використання. Його архітектура забезпечує будь-якому нативному модулю вбудовану підтримку масивних буферів, об’єктів із станом та прямої взаємодії з C++, що є можливостями, які за попередніх підходів були щонайкраще незручними або взагалі нефункціональними.
Ширша екосистема React Native почала звертати на це увагу. Проекти на кшталт react-native-nitro-cache, а також інструменти для кешування зображень, обробки даних за допомогою машинного навчання та роботи з ігровими двигунами, створюються на основі Nitro саме для зменшення навантаження від перетворень JavaScript у нативний код у тих сферах, де продуктивність має найвище значення. Це відображає загальну тенденцію в React Native, коли базові бібліотеки реструктуруються навколо Нової архітектури, а не розглядаються як щось, що можна впровадити пізніше. Використання Nitro все ще значно відстає від TurboModules, який залишається стандартним вибором для більшості бібліотек, але тенденція є очевидною. Там, де пріоритетом є первинна продуктивність, Nitro все частіше стає першим інструментом, до якого звертаються розробники.
Що це означає для авторів нативних модулів
Якщо ви наразі підтримуєте нативний модуль, ця зміна заслуговує вашої уваги. TurboModules не зникнуть найближчим часом, і для простих модулів різниця в продуктивності, ймовірно, не буде помітна для кінцевих користувачів. Однак якщо ваш модуль передбачає щось, що чутливе до продуктивності, високу частоту викликів, великі обсяги даних або об’єкти, які не можна легко перетворити на JSON, Nitro зараз, ймовірно, є кращою основою для розробки.
Вибір створення абсолютно нового нативного модуля в TurboModules у 2026 році фактично означає будування на архітектурі, яку вже перевершила швидша та продовжує розвиватися альтернатива. Генератор коду Nitro автоматично виконує значно більше повторюваних завдань одночасно на всіх трьох платформах, і результатом є більша швидкість роботи з меншою кількістю коду, написаного вручну для підтримки. Для команд, які вже мають TurboModule, міграція — це не просто клік кнопки, але саме ті ж показники продуктивності, які роблять Nitro привабливим, також створюють переконливі підстави для того, щоб провести цю міграцію якомога швидше.
React Native вже пережив кілька справжніх архітектурних поворотних моментів: відмову від старої архітектури, впровадження Нової архітектури та зараз цей. Nitro з’явився не завдяки офіційному наказу від Meta. Він з’явився тому, що одному розробнику знадобилася функціональність, яку TurboModules просто не міг надати, він створив рішення публічно та дозволив отриманим результатам тестування говорити самим за себе.
Пов’язана література
- React Native, Flutter та інші: крос-платформені мобільні додатки у 2026 році — порівняльний аналіз React Native, Flutter, Kotlin Multiplatform, Ionic, NativeScript та PWA з точки зору продуктивності, досвіду розробника та зрілості екосистеми.