Turbo Module est l'évolution des modules natifs React Native construite sur JavaScript Interface (JSI). Contrairement à Bridge, Turbo Module fonctionne de manière synchrone et sans sérialisation JSON, ce qui offre un gain de performances significatif. Selon Meta Engineering Blog, 2024, Turbo Module est un composant clé de la nouvelle architecture et est disponible dans React Native 0.76+.
L'essentiel
Turbo Module est un composant de la nouvelle architecture React Native qui remplace le Bridge classique pour la communication entre JavaScript et le code natif. Contrairement à Bridge, où chaque message est sérialisé en JSON et transmis de manière asynchrone, Turbo Module utilise JSI — une couche qui permet à JavaScript d'appeler directement des fonctions écrites en C++.
L'architecture Turbo Module a été présentée par l'équipe Meta à la React Conf 2021 dans le cadre d'une restructuration plus vaste de React Native sous le nom de code « The New Architecture ». Outre Turbo Module, la nouvelle architecture inclut Fabric (nouveau moteur de rendu), Codegen (générateur de code) et JSI (interface d'interaction). Ensemble, ces composants résolvent les problèmes de performances qui s'accumulaient dans React Native depuis 2015.
Turbo Module résout trois problèmes clés des modules natifs classiques : l'asynchronisme (tous les appels passent par une file d'attente), la sérialisation (chaque appel nécessite une transformation JSON) et le chargement (tous les modules sont initialisés au démarrage de l'application). Avec Turbo Module, les méthodes natives sont appelées de manière synchrone, les données sont transférées sans copie et les modules sont chargés à la demande.
JSI (JavaScript Interface) est une API C++ qui crée une couche entre le moteur JavaScript (Hermes ou JSC) et le code natif. JSI fournit des objets hôtes — des objets C++ qui ressemblent à des objets et méthodes JavaScript ordinaires. Lorsque JavaScript appelle une méthode d'un tel objet, JSI exécute directement le code C++ correspondant sans sérialisation et sans changement de thread.
La différence clé entre JSI et Bridge est l'absence de copie de données. Dans Bridge, chaque valeur est sérialisée en une chaîne JSON, passée par une file d'attente et désérialisée. JSI transmet des pointeurs vers les données en mémoire, ce qui permet de travailler avec de grands volumes de données sans perte de performances. Selon les tests de Meta, les appels JSI s'exécutent 5 à 10 fois plus vite que les appels équivalents via Bridge.
JSI définit l'interface HostObject — une classe C++ que React Native enregistre dans l'environnement JS comme un objet ordinaire. Lorsque le code JS accède à une propriété ou appelle une méthode de HostObject, JSI intercepte l'appel et exécute le code C++. Cela permet d'effectuer des opérations de manière synchrone sans attendre la file d'attente de Bridge.
// Exemple JSI HostObject — appel natif synchrone
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();
}
};
Le code ci-dessus montre comment JSI HostObject traite l'appel compressImage depuis JavaScript. La fonction prend deux arguments (une chaîne de chemin et un nombre de qualité), appelle la fonction native compressNative et retourne le résultat — tout de manière synchrone, sans Bridge, sans JSON. C'est l'avantage clé de JSI par rapport à l'architecture classique.
JSI fait partie de l'environnement d'exécution principal de React Native et ne dépend pas d'un moteur JavaScript spécifique. Il fonctionne aussi bien avec Hermes qu'avec JavaScriptCore (JSC), fournissant une interface unifiée pour l'interaction avec l'environnement natif.
La comparaison de Turbo Module et de Bridge montre l'évolution de l'architecture React Native. Bridge a été conçu pour le lancement rapide de React Native en 2015, mais avec la complexité croissante des applications, ses limitations sont devenues critiques. Turbo Module résout ces problèmes au niveau architectural.
| Caractéristique | Bridge | Turbo Module |
|---|---|---|
| Vitesse d'appel | 5–15 ms de surcoût | 0,1–0,5 ms de surcoût |
| Synchronicité | Uniquement asynchrone | Synchrone et asynchrone |
| Sérialisation | JSON à chaque appel | Objets JSI sans copie |
| Sécurité des types | Non | Codegen + TypeScript |
| Initialisation | Tous les modules au démarrage | Différée, à la demande |
En pratique, la différence est plus notable lors d'appels fréquents à des méthodes natives — par exemple, lors du traitement de médias ou du travail avec GPU. Pour les appels rares (une fois par session), la différence de performance est négligeable. Turbo Module simplifie également le travail avec les grandes données binaires — images, vidéos, protocoles binaires — qui nécessitaient dans Bridge des solutions de contournement avec le système de fichiers.
La création d'un Turbo Module commence par la définition d'une spécification en TypeScript. Codegen génère automatiquement des interfaces C++ et des stubs Objective-C/Java basés sur cette spécification. Cela change complètement l'approche de développement — le développeur décrit l'API une fois et Codegen crée tout le reste.
// ImageCompressor.ts — spécification 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 analyse la spécification TypeScript et génère le HostObject C++, le protocole Objective-C et l'interface Java. Il ne reste au développeur qu'à implémenter la logique native. Cette approche garantit que les types côté JavaScript et côté natif correspondent toujours, éliminant les erreurs de mapping manuel.
// Implémentation TurboModule pour iOS (stub généré)
@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
Un avantage important est le chargement différé. Turbo Module ne s'initialise pas au démarrage de l'application, mais est créé uniquement lors du premier accès depuis JavaScript. Cela réduit le temps de démarrage de l'application de 30 à 50 % par rapport à l'approche classique où tous les modules natifs sont chargés immédiatement.
La transition de Bridge vers Turbo Module ne nécessite pas de réécriture complète de l'application. React Native 0.73+ prend en charge les deux architectures en parallèle — les modules Bridge continuent de fonctionner et les nouveaux modules peuvent être créés en tant que Turbo Module. Cela permet de migrer progressivement, module par module.
Pour activer la nouvelle architecture dans un projet React Native 0.76+, définissez le drapeau newArchEnabled sur true dans le fichier react-native.config.js. Après cela, tous les modules natifs existants continuent de fonctionner via Bridge et les nouveaux modules peuvent être créés en tant que Turbo Module. Codegen gère automatiquement les deux options.
// react-native.config.js — activer la nouvelle architecture
module.exports = {
project: {
ios: {},
android: {},
},
assets: [],
newArchEnabled: true,
};
Il est recommandé de commencer la migration par les modules les plus fréquemment appelés depuis JavaScript — ce sont eux qui bénéficieront de la plus grande amélioration de performances. Les modules appelés rarement (une fois par session) peuvent rester sur Bridge sans perte de performance significative.
Questions fréquentes
Non, Turbo Module nécessite React Native 0.73+ avec la nouvelle architecture activée. À partir de la version 0.76, la nouvelle architecture est devenue stable et est recommandée pour les projets de production.
Oui, Turbo Module prend en charge les deux plateformes. JSI est une couche C++ multiplateforme et Codegen génère des stubs Objective-C et Java pour iOS et Android respectivement.
Non, Turbo Module fonctionne avec n'importe quel moteur JS via JSI. Cependant, Hermes est recommandé car il est optimisé pour fonctionner avec JSI et la nouvelle architecture React Native.
Le débogage de Turbo Module s'effectue via Xcode ou Android Studio comme du code natif classique. De plus, Flipper est disponible pour suivre les appels JSI et les performances des modules.
Turbo Module n'a pratiquement aucun impact sur la taille de l'application. Le code C++ de JSI fait déjà partie de React Native et le code généré est minimal — seulement des interfaces sans duplication de logique.
Résumé
Nous développerons une application mobile clé en main
IT Sectr crée des applications iOS et Android pour les startups et les entreprises depuis 2017. Nous vous conseillerons et vous proposerons la meilleure solution.
Lisez aussi