Turbo Module è l'evoluzione dei moduli nativi React Native costruita su JavaScript Interface (JSI). A differenza di Bridge, Turbo Module funziona in modo sincrono e senza serializzazione JSON, offrendo un significativo aumento delle prestazioni. Secondo Meta Engineering Blog, 2024, Turbo Module è un componente chiave della nuova architettura ed è disponibile in React Native 0.76+.
Punti chiave
Turbo Module è un componente della nuova architettura React Native che sostituisce il classico Bridge per la comunicazione tra JavaScript e il codice nativo. A differenza di Bridge, dove ogni messaggio viene serializzato in JSON e trasmesso in modo asincrono, Turbo Module utilizza JSI — un livello che consente a JavaScript di chiamare direttamente funzioni scritte in C++.
L'architettura Turbo Module è stata presentata dal team Meta alla React Conf 2021 come parte di una più ampia ristrutturazione di React Native con il nome in codice «The New Architecture». Oltre a Turbo Module, la nuova architettura include Fabric (nuovo renderer), Codegen (generatore di codice) e JSI (interfaccia di interazione). Insieme, questi componenti risolvono i problemi di prestazioni che si erano accumulati in React Native dal 2015.
Turbo Module risolve tre problemi chiave dei moduli nativi classici: asincronia (tutte le chiamate passano attraverso una coda), serializzazione (ogni chiamata richiede una trasformazione JSON) e caricamento (tutti i moduli vengono inizializzati all'avvio dell'app). Con Turbo Module, i metodi nativi vengono chiamati in modo sincrono, i dati vengono trasferiti senza copia e i moduli vengono caricati su richiesta.
JSI (JavaScript Interface) è un'API C++ che crea un livello tra il motore JavaScript (Hermes o JSC) e il codice nativo. JSI fornisce oggetti host — oggetti C++ che appaiono come normali oggetti e metodi JavaScript. Quando JavaScript chiama un metodo di tale oggetto, JSI esegue direttamente il codice C++ corrispondente senza serializzazione e senza cambio di thread.
La differenza chiave tra JSI e Bridge è l'assenza di copia dei dati. In Bridge, ogni valore viene serializzato in una stringa JSON, passato attraverso una coda e deserializzato. JSI passa puntatori ai dati in memoria, consentendo di lavorare con grandi volumi di dati senza perdita di prestazioni. Secondo i test di Meta, le chiamate JSI vengono eseguite da 5 a 10 volte più velocemente delle chiamate equivalenti tramite Bridge.
JSI definisce l'interfaccia HostObject — una classe C++ che React Native registra nell'ambiente JS come un oggetto normale. Quando il codice JS accede a una proprietà o chiama un metodo di HostObject, JSI intercetta la chiamata ed esegue il codice C++. Ciò consente di eseguire operazioni in modo sincrono senza attendere la coda di Bridge.
// Esempio JSI HostObject — chiamata nativa sincrona
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();
}
};
Il codice sopra dimostra come JSI HostObject gestisce la chiamata compressImage da JavaScript. La funzione accetta due argomenti (una stringa di percorso e un numero di qualità), chiama la funzione nativa compressNative e restituisce il risultato — tutto in modo sincrono, senza Bridge, senza JSON. Questo è il vantaggio chiave di JSI rispetto all'architettura classica.
JSI fa parte del runtime principale di React Native e non dipende da un motore JavaScript specifico. Funziona sia con Hermes che con JavaScriptCore (JSC), fornendo un'interfaccia unificata per l'interazione con l'ambiente nativo.
Il confronto tra Turbo Module e Bridge mostra l'evoluzione dell'architettura React Native. Bridge è stato progettato per il lancio rapido di React Native nel 2015, ma con la crescente complessità delle applicazioni, i suoi limiti sono diventati critici. Turbo Module risolve questi problemi a livello architetturale.
| Caratteristica | Bridge | Turbo Module |
|---|---|---|
| Velocità di chiamata | 5–15 ms di overhead | 0,1–0,5 ms di overhead |
| Sincronicità | Solo asincrono | Sincrono e asincrono |
| Serializzazione | JSON a ogni chiamata | Oggetti JSI senza copia |
| Type safety | No | Codegen + TypeScript |
| Inizializzazione | Tutti i moduli all'avvio | Lazy, su richiesta |
In pratica, la differenza è più evidente con chiamate frequenti a metodi nativi — ad esempio, durante l'elaborazione di media o il lavoro con GPU. Per chiamate rare (una volta per sessione), la differenza di prestazioni è trascurabile. Turbo Module semplifica anche il lavoro con grandi dati binari — immagini, video, protocolli binari — che in Bridge richiedevano soluzioni alternative con il file system.
La creazione di un Turbo Module inizia con la definizione di una specifica in TypeScript. Codegen genera automaticamente interfacce C++ e stub Objective-C/Java basati su questa specifica. Questo cambia completamente l'approccio allo sviluppo — lo sviluppatore descrive l'API una volta e Codegen crea tutto il resto.
// ImageCompressor.ts — specifica 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 analizza la specifica TypeScript e genera HostObject C++, protocollo Objective-C e interfaccia Java. Allo sviluppatore resta solo da implementare la logica nativa. Questo approccio garantisce che i tipi lato JavaScript e lato nativo corrispondano sempre, eliminando errori di mapping manuale.
// Implementazione TurboModule per iOS (stub generato)
@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 vantaggio importante è il caricamento lazy. Turbo Module non si inizializza all'avvio dell'app, ma viene creato solo al primo accesso da JavaScript. Questo riduce il tempo di avvio dell'app del 30–50% rispetto all'approccio classico in cui tutti i moduli nativi vengono caricati immediatamente.
Il passaggio da Bridge a Turbo Module non richiede una riscrittura completa dell'applicazione. React Native 0.73+ supporta entrambe le architetture in parallelo — i moduli Bridge continuano a funzionare e i nuovi moduli possono essere creati come Turbo Module. Ciò consente di migrare gradualmente, modulo per modulo.
Per abilitare la nuova architettura in un progetto React Native 0.76+, impostare il flag newArchEnabled su true nel file react-native.config.js. Dopodiché, tutti i moduli nativi esistenti continuano a funzionare tramite Bridge e i nuovi moduli possono essere creati come Turbo Module. Codegen gestisce automaticamente entrambe le opzioni.
// react-native.config.js — abilitare nuova architettura
module.exports = {
project: {
ios: {},
android: {},
},
assets: [],
newArchEnabled: true,
};
Si consiglia di iniziare la migrazione con i moduli chiamati più frequentemente da JavaScript — saranno loro a ottenere il maggiore aumento di prestazioni. I moduli chiamati raramente (una volta per sessione) possono rimanere su Bridge senza una significativa perdita di prestazioni.
Domande frequenti
No, Turbo Module richiede React Native 0.73+ con la nuova architettura abilitata. A partire dalla versione 0.76, la nuova architettura è diventata stabile ed è raccomandata per progetti in produzione.
Sì, Turbo Module supporta entrambe le piattaforme. JSI è un livello C++ multipiattaforma e Codegen genera stub Objective-C e Java rispettivamente per iOS e Android.
No, Turbo Module funziona con qualsiasi motore JS tramite JSI. Tuttavia, Hermes è raccomandato perché è ottimizzato per funzionare con JSI e la nuova architettura React Native.
Il debug di Turbo Module viene eseguito tramite Xcode o Android Studio come codice nativo normale. Inoltre, Flipper è disponibile per tracciare le chiamate JSI e le prestazioni dei moduli.
Turbo Module non ha praticamente alcun impatto sulla dimensione dell'app. Il codice C++ di JSI fa già parte di React Native e il codice generato è minimo — solo interfacce senza duplicazione di logica.
Riepilogo
Svilupperemo un'applicazione mobile chiavi in mano
IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.
Leggi anche