Bridge — adalah komponen arsitektur React Native yang menyediakan komunikasi asinkron antara thread JavaScript dan lingkungan native iOS dan Android. Ia mengirimkan pesan JSON yang telah diserialisasi melalui antrian, memungkinkan pemanggilan API native dari kode JS. Menurut Meta, 2024, Bridge tetap menjadi dasar aplikasi yang ada, meskipun kinerjanya kalah dibandingkan arsitektur baru berbasis JSI.
Poin Utama
Bridge (Jembatan) — adalah elemen arsitektur kunci React Native yang menyediakan komunikasi asinkron dua arah antara thread JavaScript, tempat logika bisnis aplikasi dijalankan, dan thread native iOS dan Android. Sejak perilisan React Native pada tahun 2015, Bridge tetap menjadi satu-satunya cara interaksi kode JS dengan API platform — kamera, geolokasi, sistem file, notifikasi, dan kemampuan native lainnya.
Arsitektur Bridge didasarkan pada prinsip antrian pesan (message queue). Ketika kode JavaScript memanggil metode native, permintaan diserialisasi menjadi string JSON, ditempatkan dalam antrian, dan dikirim secara asinkron ke sisi native. Kode native memproses permintaan, menjalankan operasi yang sesuai, dan mengirim hasilnya kembali melalui antrian yang sama ke thread JS. Menurut laporan Meta di React Conf 2021, hingga 10.000 pesan per detik melewati Bridge dalam aplikasi rata-rata.
Thread utama yang terlibat dalam kerja Bridge: JavaScript Thread (eksekusi kode JS), Native Thread (eksekusi operasi native), dan Shadow Thread (perhitungan tata letak menggunakan Yoga). Setiap thread bekerja secara independen, yang memastikan responsivitas antarmuka — animasi native tidak diblokir oleh perhitungan JS.
Bridge menggunakan tiga mekanisme kunci untuk komunikasi: MessageQueue, serialisasi JSON, dan pengelompokan pesan. MessageQueue adalah komponen internal React Native yang mengelola antrian panggilan antara JS dan sisi native. Setiap panggilan metode native ditempatkan dalam antrian, diserialisasi, dan dikirim dalam batch untuk optimasi kinerja.
MessageQueue bekerja berdasarkan prinsip pengelompokan: panggilan metode native dikumpulkan dan dikirim sebagai satu grup (batch) setiap 5–15 milidetik. Ini mengurangi overhead serialisasi karena beberapa panggilan dikemas dalam satu paket JSON. Di sisi native, pesan dideserialisasi dan didistribusikan ke modul yang sesuai.
Modul native didaftarkan secara otomatis melalui makro atau anotasi. Di iOS, makro RCT_EXPORT_MODULE digunakan, di Android — anotasi @ReactMethod. React Native memindai modul yang terdaftar saat aplikasi dimulai dan membangun peta JSON konfigurasi dari semua metode yang tersedia. Peta ini dikirim ke lingkungan JS, dan JavaScript mengetahui metode apa yang dapat dipanggil.
Data melewati jalur berikut: JavaScript memanggil NativeModules.CalendarModule.createCalendarEvent(). Metode diserialisasi menjadi pesan JSON dengan ID modul, nama metode, dan argumen. Pesan masuk ke antrian MessageQueue. Di thread native, pesan dideserialisasi dan diteruskan ke modul yang sesuai. Hasil eksekusi diserialisasi kembali dan dikirim ke thread JS sebagai Promise atau callback.
// Panggilan modul native dari JavaScript melalui Bridge
import { NativeModules } from 'react-native';
const CalendarModule = NativeModules.CalendarModule;
CalendarModule.createCalendarEvent('Test Event', 'Office')
.then(eventId => {
console.log('Acara dibuat dengan id:', eventId);
})
.catch(error => {
console.error('Gagal:', error);
});
Di sisi native iOS, modul terlihat seperti kelas Objective-C dengan makro RCT_EXPORT_MODULE. Metode diekspor dengan makro RCT_EXPORT_METHOD, dan React Native secara otomatis mendaftarkannya di Bridge. Argumen dilewatkan berdasarkan posisi dan harus sesuai dengan tipe JSON yang didukung: NSString, NSNumber, NSArray, NSDictionary, BOOL.
// Pendaftaran Modul Native iOS di 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 memiliki sejumlah batasan kinerja fundamental. Yang utama adalah asinkronisitas wajib dan serialisasi. Setiap panggilan metode native mengubah data menjadi string JSON, yang menambah latensi dan menghabiskan memori. Untuk operasi dengan volume data besar, seperti pemrosesan gambar atau bekerja dengan video, ini menjadi hambatan.
Serialisasi dan deserialisasi JSON memakan waktu prosesor dan memori. Setiap pesan harus diubah menjadi string di sisi JS, dikirim melalui jembatan, dan diuraikan di sisi native. Menurut tes Callstack (2022), serialisasi array 10.000 angka melalui Bridge memakan waktu sekitar 30–50 milidetik, yang tidak dapat diterima untuk panggilan frekuensi tinggi.
Bridge tidak dioptimalkan untuk mengirim data biner besar. Foto, file audio, dan streaming video memerlukan pendekatan alternatif — misalnya, menulis file ke disk dan mengirim jalurnya sebagai string. Ini menciptakan overhead tambahan untuk membaca dan menulis sistem file.
Kesadaran akan batasan ini menyebabkan tim Meta mengembangkan arsitektur baru React Native, di mana Bridge digantikan oleh JSI (JavaScript Interface) dan Turbo Module. JSI memungkinkan pemanggilan langsung metode native tanpa serialisasi, yang menghilangkan kelemahan utama Bridge.
Perbandingan Bridge dan Turbo Module menunjukkan perbedaan mendasar dalam pendekatan arsitektur. Bridge menggunakan antrian pesan asinkron dengan serialisasi JSON, sementara Turbo Module bekerja melalui JSI — antarmuka langsung antara JavaScript dan C++ yang memungkinkan pemanggilan sinkron metode native tanpa konversi data.
| Karakteristik | Bridge | Turbo Module |
|---|---|---|
| Tipe panggilan | Asinkron | Sinkron dan asinkron |
| Serialisasi | JSON setiap panggilan | Objek JSI tanpa penyalinan |
| Kinerja | Sedang | Tinggi |
| Pengetikan | Dinamis | Statis (Codegen) |
| Pemuatan | Semua modul saat startup | Malas (sesuai permintaan) |
Pilihan antara Bridge dan Turbo Module tergantung pada versi React Native. Untuk proyek pada React Native 0.72 dan lebih lama, Bridge tetap menjadi mekanisme utama. Mulai dari React Native 0.73, Metro dan arsitektur baru didukung secara paralel, memungkinkan migrasi bertahap. Transisi penuh ke Turbo Module memerlukan pembaruan ke React Native 0.76+ dan mengaktifkan arsitektur baru dalam konfigurasi.
Mari kita lihat siklus lengkap pembuatan dan penggunaan Native Module melalui Bridge dengan contoh modul untuk bekerja dengan kalender. Modul akan membuat acara dan mengembalikan pengidentifikasinya. Contoh ini mencakup pengaturan untuk kedua platform — iOS dan Android.
Di Android, Native Module dibuat sebagai kelas Java yang mewarisi ReactContextBaseJavaModule. Anotasi @ReactMethod mengekspor metode ke Bridge. Untuk Promise, antarmuka Promise dari com.facebook.react.bridge digunakan.
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());
}
}
}
Modul didaftarkan melalui @ReactModule atau secara manual dalam paket aplikasi. React Native secara otomatis mendeteksinya dan menambahkannya ke Bridge. Setelah pendaftaran, modul dapat diakses dari JavaScript melalui NativeModules.
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();
}
}
Penting untuk dicatat bahwa Bridge memerlukan restart aplikasi saat menambahkan modul baru, karena peta konfigurasi dibangun sekali saat inisialisasi. Ini membedakannya dari Turbo Module, yang dimuat secara malas dan mendukung hot-reload modul tanpa restart.
Pertanyaan yang Sering Diajukan
Bridge selalu menggunakan antrian asinkron dan serialisasi JSON, sementara transfer langsung melalui JSI bekerja secara sinkron dan tanpa menyalin data. Bridge menciptakan latensi untuk serialisasi, tetapi memastikan isolasi thread.
Tidak, Bridge hanya mendukung panggilan asinkron. Untuk interaksi sinkron, diperlukan arsitektur baru dengan JSI dan Turbo Module. Ini adalah salah satu batasan utama yang telah diselesaikan di React Native 0.76+.
Bridge mendukung tipe yang dapat diserialisasi ke JSON: string, angka, boolean, array, kamus (objek). Data biner seperti gambar harus dikirim melalui sistem file atau pengkodean base64.
Untuk mengukur, gunakan React DevTools dan profiler React Native. Tab Performance menunjukkan jumlah pesan dalam antrian Bridge dan latensi. Juga tersedia paket react-native-bridge-spy untuk pemantauan lalu lintas.
Peralihan direkomendasikan untuk proyek yang membutuhkan kinerja tinggi atau saat membuat aplikasi baru di React Native 0.76+. Untuk proyek yang ada, migrasi dapat dilakukan secara bertahap — kedua arsitektur berjalan paralel.
Ringkasan
Kami akan mengembangkan aplikasi seluler turnkey
IT Sectr membuat aplikasi iOS dan Android untuk startup dan bisnis sejak 2017. Kami akan memberi saran dan mengusulkan solusi terbaik.
Baca juga