Bridge ist eine architektonische Komponente von React Native, die eine asynchrone Kommunikation zwischen dem JavaScript-Thread und der nativen Umgebung von iOS und Android ermöglicht. Sie überträgt serialisierte JSON-Nachrichten über eine Warteschlange und ermöglicht es, native APIs aus JS-Code aufzurufen. Laut Meta, 2024 bleibt Bridge die Grundlage bestehender Anwendungen, auch wenn sie in der Leistung gegenüber der neuen Architektur auf JSI zurücksteht.
Wichtige Punkte
Bridge ist ein wichtiges architektonisches Element von React Native, das eine bidirektionale asynchrone Kommunikation zwischen dem JavaScript-Thread, in dem die Geschäftslogik der Anwendung ausgeführt wird, und den nativen iOS- und Android-Threads ermöglicht. Seit der Veröffentlichung von React Native im Jahr 2015 war Bridge die einzige Möglichkeit für JS-Code, mit Plattform-APIs zu interagieren — Kamera, Geolokalisierung, Dateisystem, Benachrichtigungen und andere native Funktionen.
Die Bridge-Architektur basiert auf dem Prinzip der Nachrichtenwarteschlange (Message Queue). Wenn JavaScript-Code eine native Methode aufruft, wird die Anfrage in einen JSON-String serialisiert, in eine Warteschlange gestellt und asynchron an die native Seite gesendet. Der native Code verarbeitet die Anfrage, führt die entsprechende Operation aus und sendet das Ergebnis über dieselbe Warteschlange zurück an den JS-Thread. Laut einem Bericht von Meta auf der React Conf 2021 passieren in einer durchschnittlichen Anwendung bis zu 10.000 Nachrichten pro Sekunde durch Bridge.
Die wichtigsten Threads, die am Bridge-Betrieb beteiligt sind: JavaScript Thread (Ausführung von JS-Code), Native Thread (Ausführung nativer Operationen) und Shadow Thread (Layout-Berechnung mit Yoga). Jeder Thread arbeitet unabhängig, was die Reaktionsfähigkeit der UI gewährleistet — native Animationen werden nicht durch JS-Berechnungen blockiert.
Bridge verwendet drei Schlüsselmechanismen für die Kommunikation: MessageQueue, JSON-Serialisierung und Nachrichten-Batching. MessageQueue ist eine interne React Native-Komponente, die die Aufrufwarteschlange zwischen JS und der nativen Seite verwaltet. Jeder native Methodenaufruf wird in eine Warteschlange gestellt, serialisiert und zur Leistungsoptimierung in Batches gesendet.
MessageQueue arbeitet nach dem Batching-Prinzip: native Methodenaufrufe sammeln sich an und werden alle 5–15 Millisekunden als eine einzelne Gruppe (Batch) gesendet. Dies reduziert den Serialisierungsaufwand, da mehrere Aufrufe in ein einziges JSON-Paket verpackt werden. Auf der nativen Seite werden die Nachrichten deserialisiert und an die entsprechenden Module verteilt.
Native Module werden automatisch über Makros oder Annotationen registriert. iOS verwendet das RCT_EXPORT_MODULE-Makro, Android die @ReactMethod-Annotation. React Native scannt die registrierten Module beim Anwendungsstart und erstellt eine JSON-Konfigurationskarte aller verfügbaren Methoden. Diese Karte wird an die JS-Umgebung übergeben, und JavaScript erfährt, welche Methoden aufgerufen werden können.
Die Daten durchlaufen folgenden Pfad: JavaScript ruft NativeModules.CalendarModule.createCalendarEvent() auf. Die Methode wird in eine JSON-Nachricht mit Modulbezeichner, Methodennamen und Argumenten serialisiert. Die Nachricht gelangt in die MessageQueue. Im nativen Thread wird die Nachricht deserialisiert und an das entsprechende Modul weitergeleitet. Das Ausführungsergebnis wird zurück serialisiert und als Promise oder Callback an den JS-Thread gesendet.
// Native module call from JavaScript via Bridge
import { NativeModules } from 'react-native';
const CalendarModule = NativeModules.CalendarModule;
CalendarModule.createCalendarEvent('Test Event', 'Office')
.then(eventId => {
console.log('Created event with id:', eventId);
})
.catch(error => {
console.error('Failed:', error);
});
Auf der nativen iOS-Seite sieht das Modul wie eine Objective-C-Klasse mit dem RCT_EXPORT_MODULE-Makro aus. Die Methode wird mit dem RCT_EXPORT_METHOD-Makro exportiert, und React Native registriert sie automatisch in Bridge. Die Argumente werden positionsbasiert übergeben und müssen den unterstützten JSON-Typen entsprechen: NSString, NSNumber, NSArray, NSDictionary, BOOL.
// iOS Native Module registration in Bridge
@interface CalendarModule () RCT_EXPORT_MODULE()
@end
@implementation CalendarModule
RCT_EXPORT_METHOD(createCalendarEvent:(NSString *)name
location:(NSString *)location
resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
{
NSNumber *eventId = createEvent(name, location);
resolve(eventId);
}
@end
Bridge hat eine Reihe grundlegender Leistungseinschränkungen. Die wichtigste ist die zwingende Asynchronität und Serialisierung. Jeder native Methodenaufruf wandelt Daten in einen JSON-String um, was Latenz hinzufügt und Speicher verbraucht. Bei Operationen mit großen Datenmengen, wie Bildverarbeitung oder Videobearbeitung, wird dies zum Engpass.
JSON-Serialisierung und -Deserialisierung verbrauchen CPU-Zeit und Speicher. Jede Nachricht muss auf der JS-Seite in einen String umgewandelt, über die Brücke übertragen und auf der nativen Seite analysiert werden. Laut Tests von Callstack (2022) dauert die Serialisierung eines Arrays von 10.000 Zahlen über Bridge etwa 30–50 Millisekunden, was für hochfrequente Aufrufe inakzeptabel ist.
Bridge ist nicht für die Übertragung großer Binärdaten optimiert. Fotos, Audiodateien und Videostreams erfordern alternative Ansätze — zum Beispiel das Schreiben einer Datei auf die Festplatte und die Übergabe des Pfads als String. Dies schafft zusätzlichen Aufwand für Lese- und Schreibvorgänge des Dateisystems.
Die Erkenntnis dieser Einschränkungen führte das Meta-Team zur Entwicklung einer neuen React Native-Architektur, bei der Bridge durch JSI (JavaScript Interface) und Turbo Module ersetzt wird. JSI ermöglicht den direkten Aufruf nativer Methoden ohne Serialisierung und beseitigt damit den Hauptnachteil von Bridge.
Der Vergleich von Bridge und Turbo Module zeigt grundlegende Unterschiede in den architektonischen Ansätzen. Bridge verwendet eine asynchrone Nachrichtenwarteschlange mit JSON-Serialisierung, während Turbo Module über JSI arbeitet — eine direkte Schnittstelle zwischen JavaScript und C++, die synchrone Aufrufe nativer Methoden ohne Datenkonvertierung ermöglicht.
| Eigenschaft | Bridge | Turbo Module |
|---|---|---|
| Aufrufart | Asynchron | Synchrone und asynchron |
| Serialisierung | JSON bei jedem Aufruf | JSI-Objekte ohne Kopieren |
| Leistung | Mittel | Hoch |
| Typisierung | Dynamisch | Statisch (Codegen) |
| Laden | Alle Module beim Start | Lazy (auf Anfrage) |
Die Wahl zwischen Bridge und Turbo Module hängt von der React Native-Version ab. Für Projekte mit React Native 0.72 und älter bleibt Bridge der Hauptmechanismus. Ab React Native 0.73 werden Metro und die neue Architektur parallel unterstützt, was eine schrittweise Migration ermöglicht. Ein vollständiger Wechsel zu Turbo Module erfordert ein Update auf React Native 0.76+ und die Aktivierung der neuen Architektur in der Konfiguration.
Gehen wir den gesamten Zyklus der Erstellung und Verwendung eines Native Modules über Bridge am Beispiel eines Kalendermoduls durch. Das Modul erstellt ein Ereignis und gibt seine Kennung zurück. Dieses Beispiel deckt die Einrichtung für beide Plattformen ab — iOS und Android.
Auf Android wird ein Native Module als Java-Klasse erstellt, die ReactContextBaseJavaModule erweitert. Die @ReactMethod-Annotation exportiert die Methode nach Bridge. Für Promise wird das Promise-Interface aus com.facebook.react.bridge verwendet.
public class CalendarModule extends ReactContextBaseJavaModule {
@Override
public String getName() {
return "CalendarModule";
}
@ReactMethod
public void createCalendarEvent(
String name,
String location,
Promise promise) {
try {
Integer eventId = createCalendarEventNative(name, location);
promise.resolve(eventId);
} catch (Exception e) {
promise.reject("EVENT_ERROR", e.getMessage());
}
}
}
Das Modul wird über @ReactModule oder manuell im Anwendungspaket registriert. React Native erkennt es automatisch und fügt es zu Bridge hinzu. Nach der Registrierung ist das Modul von JavaScript aus über NativeModules zugänglich.
public class CalendarPackage implements ReactPackage {
@Override
public List<NativeModule> createNativeModules(
ReactApplicationContext reactContext) {
return Arrays.asList(
new CalendarModule(reactContext)
);
}
@Override
public List<ViewManager> createViewManagers(
ReactApplicationContext reactContext) {
return Collections.emptyList();
}
}
Es ist wichtig zu beachten, dass Bridge beim Hinzufügen neuer Module einen Neustart der Anwendung erfordert, da die Konfigurationskarte einmal während der Initialisierung erstellt wird. Dies unterscheidet ihn von Turbo Module, das lazy geladen wird und Hot-Reload von Modulen ohne Neustart unterstützt.
Häufig gestellte Fragen
Bridge verwendet immer eine asynchrone Warteschlange und JSON-Serialisierung, während die direkte Übertragung über JSI synchron und ohne Datenkopie arbeitet. Bridge erzeugt Serialisierungslatenz, gewährleistet aber die Isolation der Threads.
Nein, Bridge unterstützt nur asynchrone Aufrufe. Für synchrone Interaktion ist die neue Architektur mit JSI und Turbo Module erforderlich. Dies ist eine der wichtigsten Einschränkungen, die in React Native 0.76+ behoben wurde.
Bridge unterstützt in JSON serialisierbare Typen: Zeichenketten, Zahlen, boolesche Werte, Arrays, Wörterbücher (Objekte). Binärdaten wie Bilder müssen über das Dateisystem oder Base64-Kodierung übertragen werden.
Zur Messung verwenden Sie React DevTools und den React Native-Profiler. Der Reiter Performance zeigt die Anzahl der Nachrichten in der Bridge-Warteschlange und die Latenzen. Das Paket react-native-bridge-spy ist ebenfalls für die Verkehrsüberwachung verfügbar.
Empfohlen wird der Wechsel bei leistungsintensiven Projekten oder bei der Erstellung neuer Anwendungen auf React Native 0.76+. Für bestehende Projekte kann die Migration schrittweise erfolgen — beide Architekturen arbeiten parallel.
Zusammenfassung
Wir entwickeln eine mobile Applikation schlüsselfertig
IT Sectr entwickelt seit 2017 iOS- und Android-Apps für Startups und Unternehmen. Wir beraten Sie und schlagen die beste Lösung vor.
Lesen Sie auch