Turbo Module е еволюцията на нативните модули на React Native, изградена върху JavaScript Interface (JSI). За разлика от Bridge, Turbo Module работи синхронно и без JSON сериализация, което дава значително увеличение на производителността. Според Meta Engineering Blog, 2024, Turbo Module е ключов компонент на новата архитектура и е достъпен в React Native 0.76+.
Основни точки
Turbo Module е компонент на новата архитектура на React Native, който заменя класическия Bridge за взаимодействие на JavaScript с нативен код. За разлика от Bridge, където всяко съобщение се сериализира в JSON и се изпраща асинхронно, Turbo Module използва JSI — междинен слой, който позволява на JavaScript директно да извиква функции, написани на C++.
Архитектурата на Turbo Module беше представена от екипа на Meta на React Conf 2021 като част от по-мащабно преустройство на React Native под кодовото име „The New Architecture“. Освен Turbo Module, новата архитектура включва Fabric (нов рендерер), Codegen (генератор на код) и JSI (комуникационен интерфейс). Заедно тези компоненти решават проблемите с производителността, които се натрупваха в React Native от 2015 г.
Turbo Module решава три ключови проблема на класическите нативни модули: асинхронност (всички извиквания минават през опашка), сериализация (всяко извикване изисква JSON конвертиране) и зареждане (всички модули се инициализират при стартиране на приложението). С Turbo Module нативните методи се извикват синхронно, данните се прехвърлят без копиране, а модулите се зареждат при поискване.
JSI (JavaScript Interface) е C++ API, който създава междинен слой между JavaScript двигателя (Hermes или JSC) и нативния код. JSI предоставя хост обекти — C++ обекти, които изглеждат като обикновени JavaScript обекти и методи. Когато JavaScript извика метод на такъв обект, JSI директно изпълнява съответния C++ код без сериализация и без превключване на нишки.
Ключовата разлика между JSI и Bridge — липсата на копиране на данни. В Bridge всяка стойност се сериализира в JSON, изпраща се през опашка и се десериализира. JSI предава указатели към данни в паметта, което позволява работа с големи обеми данни без загуба на производителност. Според тестовете на Meta, JSI извикванията са 5–10 пъти по-бързи от аналогичните извиквания през Bridge.
JSI дефинира интерфейса HostObject — C++ клас, който React Native регистрира в JS средата като обикновен обект. Когато JS код достъпи свойство или извика метод на HostObject, JSI прихваща извикването и изпълнява C++ кода. Това позволява извършване на операции синхронно, без изчакване на опашката на Bridge.
// Пример за JSI HostObject — синхронно нативно извикване
class ImageCompressorHostObject : public jsi::HostObject {
jsi::Value get(
jsi::Runtime& rt,
const jsi::PropNameID& propName
) override {
auto name = propName.utf8(rt);
if (name == "compressImage") {
return jsi::Function::createFromHostFunction(
rt,
jsi::PropNameID::forUtf8(rt, name),
2,
[](jsi::Runtime& rt,
const jsi::Value& thisValue,
const jsi::Value* args,
size_t count) -> jsi::Value {
return jsi::Value(rt, compressNative(
args[0].asString(rt).utf8(rt),
args[1].asNumber()
));
}
);
}
return jsi::Value::undefined();
}
};
Горният код показва как JSI HostObject обработва извикването compressImage от JavaScript. Функцията приема два аргумента (път и качество), извиква нативната функция compressNative и връща резултата — всичко синхронно, без Bridge, без JSON. Това е ключовото предимство на JSI пред класическата архитектура.
JSI е част от главната среда за изпълнение на React Native и не зависи от конкретен JavaScript двигател. Работи както с Hermes, така и с JavaScriptCore (JSC), предоставяйки унифициран интерфейс за комуникация с нативната среда.
Сравнението на Turbo Module и Bridge показва еволюцията на архитектурата на React Native. Bridge беше проектиран за бързо стартиране на React Native през 2015 г., но с нарастването на сложността на приложенията неговите ограничения станаха критични. Turbo Module решава тези проблеми на архитектурно ниво.
| Характеристика | Bridge | Turbo Module |
|---|---|---|
| Скорост на извикване | 5–15 ms overhead | 0.1–0.5 ms overhead |
| Синхронност | Само асинхронно | Синхронно и асинхронно |
| Сериализация | JSON при всяко извикване | JSI обекти без копиране |
| Типова безопасност | Не | Codegen + TypeScript |
| Инициализация | Всички модули при старт | Мързеливо, при поискване |
На практика разликата е най-забележима при чести извиквания на нативни методи — например при обработка на медии или работа с GPU. За редки извиквания (веднъж на сесия) разликата в производителността е незначителна. Turbo Module също така опростява работата с големи бинарни данни — изображения, видео, бинарни протоколи — които в Bridge изискваха решения с файловата система.
Създаването на Turbo Module започва с дефиниране на спецификация в TypeScript. Codegen автоматично генерира C++ интерфейси и Objective-C/Java заглушки въз основа на тази спецификация. Това напълно променя подхода към разработката — разработчикът описва API веднъж, а Codegen създава всичко останало.
// ImageCompressor.ts — спецификация на Turbo Module
import type { TurboModule } from 'react-native';
import type { Double } from 'react-native/Libraries/Types/CodegenTypes';
export interface Spec extends TurboModule {
compressImage(
imagePath: string,
quality: Double
): Promise<string>;
}
Codegen анализира TypeScript спецификацията и генерира C++ HostObject, Objective-C протокол и Java интерфейс. На разработчика остава само да имплементира нативната логика. Този подход гарантира, че типовете от страна на JavaScript и нативната страна винаги съвпадат, елиминирайки грешките при ръчно картографиране.
// Имплементация на TurboModule за iOS (генерирана заглушка)
@interface ImageCompressorModule ()
RCT_EXPORT_MODULE(ImageCompressor)
@end
@implementation ImageCompressorModule
RCT_EXPORT_METHOD(compressImage:(NSString *)imagePath
quality:(NSNumber *)quality
resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
{
NSData *compressed = [ImageProcessor compressAtPath:imagePath
quality:quality.doubleValue];
resolve([NSString stringWithUTF8String:compressed.UTF8String]);
}
@end
Важно предимство — мързеливо зареждане. Turbo Module не се инициализира при стартиране на приложението, а се създава едва при първи достъп от JavaScript. Това намалява времето за стартиране на приложението с 30–50% в сравнение с класическия подход, при който всички нативни модули се зареждат веднага.
Преходът от Bridge към Turbo Module не изисква пълно пренаписване на приложението. React Native 0.73+ поддържа и двете архитектури паралелно — Bridge модулите продължават да работят, а новите модули могат да се създават като Turbo Module. Това позволява постепенна миграция, модул по модул.
За да включите новата архитектура в проект с React Native 0.76+, задайте флага newArchEnabled на true във файла react-native.config.js. След това всички съществуващи нативни модули продължават да работят чрез Bridge, а новите модули могат да се създават като Turbo Module. Codegen автоматично обработва и двата варианта.
// react-native.config.js — включване на нова архитектура
module.exports = {
project: {
ios: {},
android: {},
},
assets: [],
newArchEnabled: true,
};
Препоръчва се да започнете миграцията с модулите, които най-често се извикват от JavaScript — те ще получат най-голямо увеличение на производителността. Модулите, които се извикват рядко (веднъж на сесия), могат да останат на Bridge без значителна загуба на производителност.
Често задавани въпроси
Не, Turbo Module изисква React Native 0.73+ с включена нова архитектура. От версия 0.76 новата архитектура стана стабилна и се препоръчва за производствени проекти.
Да, Turbo Module поддържа и двете платформи. JSI е междуплатформен C++ слой, а Codegen генерира Objective-C и Java заглушки съответно за iOS и Android.
Не, Turbo Module работи с всеки JS двигател чрез JSI. Въпреки това Hermes се препоръчва, тъй като е оптимизиран за работа с JSI и новата архитектура на React Native.
Дебъгването на Turbo Module се извършва чрез Xcode или Android Studio като обикновен нативен код. Допълнително е наличен Flipper за проследяване на JSI извиквания и производителност на модулите.
Turbo Module практически не влияе на размера на приложението. C++ кодът на JSI вече е част от React Native, а генерираният код е минимален — само интерфейси без дублиране на логика.
Обобщение
Ще разработим мобилно приложение под ключ
IT Sectr създава iOS и Android приложения за стартъпи и бизнеси от 2017 г. Ще ви консултираме и ще предложим най-доброто решение.
Прочетете също