Bridge w React Native — co to jest, zasada działania i interakcja

Autor: IT Sectr Opublikowano: 2026-06-03 Czas czytania: 9 min

Bridge — to architektoniczny komponent React Native, zapewniający asynchroniczną komunikację między wątkiem JavaScript a środowiskiem natywnym iOS i Android. Przesyła zserializowane wiadomości JSON przez kolejkę, umożliwiając wywoływanie natywnych API z kodu JS. Według Meta, 2024, Bridge pozostaje podstawą istniejących aplikacji, choć ustępuje wydajnością nowej architekturze opartej na JSI.

Najważniejsze

  • Bridge — asynchroniczny kanał komunikacji między JavaScript a kodem natywnym w React Native.
  • Serializacja — wszystkie dane są przekształcane do JSON przed przesłaniem, co generuje narzut wydajnościowy.
  • Asynchroniczność — wiadomości są przesyłane przez kolejkę, więc JS nie blokuje wątku natywnego.
  • Ograniczenia — Bridge nie nadaje się do częstych, drobnych wywołań ze względu na koszty serializacji.
  • Zastąpienie — w nowej architekturze React Native Bridge jest zastępowany przez JSI i Turbo Module.

Czym jest Bridge w React Native?

Bridge (Most) — to kluczowy element architektoniczny React Native, który zapewnia dwukierunkową asynchroniczną komunikację między wątkiem JavaScript, w którym wykonywana jest logika biznesowa aplikacji, a natywnymi wątkami iOS i Android. Od momentu wydania React Native w 2015 roku Bridge pozostawał jedynym sposobem interakcji kodu JS z platformowymi API — aparat, geolokalizacja, system plików, powiadomienia i inne natywne możliwości.

Architektura Bridge opiera się na zasadzie kolejki komunikatów (message queue). Gdy kod JavaScript wywołuje metodę natywną, żądanie jest serializowane do ciągu JSON, umieszczane w kolejce i asynchronicznie wysyłane na stronę natywną. Kod natywny przetwarza żądanie, wykonuje odpowiednią operację i wysyła wynik z powrotem przez tę samą kolejkę do wątku JS. Według raportu Meta na React Conf 2021, przez Bridge przechodzi do 10 000 wiadomości na sekundę w przeciętnej aplikacji.

Główne wątki uczestniczące w działaniu Bridge: JavaScript Thread (wykonanie kodu JS), Native Thread (wykonanie operacji natywnych) i Shadow Thread (obliczanie układu za pomocą Yoga). Każdy wątek działa niezależnie, co zapewnia responsywność interfejsu — natywne animacje nie są blokowane przez obliczenia JS.

Jak działa architektura Bridge

Bridge wykorzystuje trzy kluczowe mechanizmy komunikacji: MessageQueue, serializację JSON i grupowanie wiadomości. MessageQueue to wewnętrzny komponent React Native, który zarządza kolejką wywołań między JS a stroną natywną. Każde wywołanie metody natywnej jest umieszczane w kolejce, serializowane i wysyłane w partiach w celu optymalizacji wydajności.

MessageQueue i serializacja

MessageQueue działa na zasadzie grupowania: wywołania metod natywnych są akumulowane i wysyłane jako jedna grupa (batch) co 5–15 milisekund. Zmniejsza to narzut na serializację, ponieważ kilka wywołań jest pakowanych w jeden pakiet JSON. Po stronie natywnej wiadomości są deserializowane i rozdzielane do odpowiednich modułów.

Rejestracja modułów

Moduły natywne są rejestrowane automatycznie przez makra lub adnotacje. W iOS używane jest makro RCT_EXPORT_MODULE, w Androidzie — adnotacja @ReactMethod. React Native skanuje zarejestrowane moduły podczas uruchamiania aplikacji i tworzy konfiguracyjną mapę JSON wszystkich dostępnych metod. Ta mapa jest przekazywana do środowiska JS, a JavaScript dowiaduje się, jakie metody można wywoływać.

Przepływ danych

Dane przechodzą następującą ścieżkę: JavaScript wywołuje NativeModules.CalendarModule.createCalendarEvent(). Metoda jest serializowana do wiadomości JSON z identyfikatorem modułu, nazwą metody i argumentami. Wiadomość trafia do kolejki MessageQueue. W wątku natywnym wiadomość jest deserializowana i przekazywana do odpowiedniego modułu. Wynik wykonania jest serializowany z powrotem i wysyłany do wątku JS jako Promise lub callback.

js
            // Wywołanie modułu natywnego z JavaScript przez Bridge
import { NativeModules } from 'react-native';

const CalendarModule = NativeModules.CalendarModule;

CalendarModule.createCalendarEvent('Test Event', 'Office')
  .then(eventId => {
    console.log('Utworzono zdarzenie o id:', eventId);
  })
  .catch(error => {
    console.error('Niepowodzenie:', error);
  });

Po stronie natywnej iOS moduł wygląda jak klasa Objective-C z makrem RCT_EXPORT_MODULE. Metoda jest eksportowana za pomocą makra RCT_EXPORT_METHOD, a React Native automatycznie rejestruje ją w Bridge. Argumenty są przekazywane według pozycji i muszą odpowiadać obsługiwanym typom JSON: NSString, NSNumber, NSArray, NSDictionary, BOOL.

objective-c
            // Rejestracja natywnego modułu iOS w 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

Ograniczenia i problemy Bridge

Bridge ma szereg fundamentalnych ograniczeń wydajnościowych. Głównym z nich jest obowiązkowa asynchroniczność i serializacja. Każde wywołanie metody natywnej przekształca dane w ciąg JSON, co dodaje opóźnienie i zużywa pamięć. W przypadku operacji na dużych ilościach danych, takich jak przetwarzanie obrazów czy praca z wideo, staje się to wąskim gardłem.

Koszty serializacji

Serializacja i deserializacja JSON zajmują czas procesora i pamięć. Każda wiadomość musi zostać przekształcona w ciąg po stronie JS, przesłana przez most i sparsowana po stronie natywnej. Według testów Callstack (2022), serializacja tablicy 10 000 liczb przez Bridge zajmuje około 30–50 milisekund, co jest nieakceptowalne dla wywołań o wysokiej częstotliwości.

Ograniczenie rozmiaru wiadomości

Bridge nie jest zoptymalizowany do przesyłania dużych danych binarnych. Zdjęcia, pliki audio i strumienie wideo wymagają alternatywnych podejść — na przykład zapisu pliku na dysk i przesłania ścieżki jako ciągu znaków. Tworzy to dodatkowy narzut na odczyt i zapis systemu plików.

  • Asynchroniczność — Bridge nie obsługuje wywołań synchronicznych, co utrudnia scenariusze wymagające natychmiastowej odpowiedzi.
  • Pamięć — każda wiadomość jest przechowywana w kolejce do momentu przetworzenia, co może prowadzić do wzrostu zużycia pamięci.
  • Debugowanie — śledzenie wiadomości w Bridge jest utrudnione, ponieważ łańcuch wywołań jest przerywany między wątkami.

Świadomość tych ograniczeń doprowadziła zespół Meta do opracowania nowej architektury React Native, w której Bridge jest zastępowany przez JSI (JavaScript Interface) i Turbo Module. JSI umożliwia bezpośrednie wywoływanie metod natywnych bez serializacji, co eliminuje główną wadę Bridge.

Bridge vs Turbo Module: porównanie

Porównanie Bridge i Turbo Module pokazuje fundamentalne różnice w podejściach architektonicznych. Bridge używa asynchronicznej kolejki komunikatów z serializacją JSON, podczas gdy Turbo Module działa przez JSI — bezpośredni interfejs między JavaScript a C++, który umożliwia synchroniczne wywoływanie metod natywnych bez przekształcania danych.

CechaBridgeTurbo Module
Typ wywołaniaAsynchronicznySynchroniczny i asynchroniczny
SerializacjaJSON przy każdym wywołaniuObiekty JSI bez kopiowania
WydajnośćŚredniaWysoka
TypowanieDynamiczneStatyczne (Codegen)
ŁadowanieWszystkie moduły przy starcieLeniwie (na żądanie)

Wybór między Bridge a Turbo Module zależy od wersji React Native. Dla projektów na React Native 0.72 i starszych Bridge pozostaje głównym mechanizmem. Począwszy od React Native 0.73, Metro i nowa architektura są obsługiwane równolegle, umożliwiając stopniową migrację. Pełne przejście na Turbo Module wymaga aktualizacji do React Native 0.76+ i włączenia nowej architektury w konfiguracji.

Przykład konfiguracji Native Module przez Bridge

Rozważmy pełny cykl tworzenia i używania Native Module przez Bridge na przykładzie modułu do pracy z kalendarzem. Moduł będzie tworzyć wydarzenie i zwracać jego identyfikator. Ten przykład obejmuje konfigurację dla obu platform — iOS i Android.

Moduł Android

W Androidzie Native Module jest tworzony jako klasa Java dziedzicząca po ReactContextBaseJavaModule. Adnotacja @ReactMethod eksportuje metodę do Bridge. Dla Promise używany jest interfejs Promise z com.facebook.react.bridge.

java
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());
        }
    }
}

Rejestracja i użycie

Moduł jest rejestrowany przez @ReactModule lub ręcznie w pakiecie aplikacji. React Native automatycznie wykrywa i dodaje go do Bridge. Po rejestracji moduł jest dostępny z JavaScript przez NativeModules.

java
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();
    }
}

Ważne jest, że Bridge wymaga ponownego uruchomienia aplikacji przy dodawaniu nowych modułów, ponieważ mapa konfiguracyjna jest budowana raz podczas inicjalizacji. To odróżnia go od Turbo Module, który ładuje się leniwie i obsługuje hot-reload modułów bez restartu.

Często zadawane pytania

Czym Bridge różni się od bezpośredniego przesyłania danych?

Bridge zawsze używa asynchronicznej kolejki i serializacji JSON, podczas gdy bezpośrednie przesyłanie przez JSI działa synchronicznie i bez kopiowania danych. Bridge tworzy opóźnienie na serializację, ale zapewnia izolację wątków.

Czy można wywoływać metody synchronicznie przez Bridge?

Nie, Bridge obsługuje tylko wywołania asynchroniczne. Do synchronicznej interakcji wymagana jest nowa architektura z JSI i Turbo Module. To jedno z kluczowych ograniczeń, które zostało rozwiązane w React Native 0.76+.

Jakie typy danych obsługuje Bridge?

Bridge obsługuje typy serializowalne do JSON: ciągi znaków, liczby, wartości logiczne, tablice, słowniki (obiekty). Dane binarne, takie jak obrazy, należy przesyłać przez system plików lub kodowanie base64.

Jak zmierzyć wydajność Bridge?

Do pomiaru użyj React DevTools i profilera React Native. Zakładka Performance pokazuje liczbę wiadomości w kolejce Bridge i opóźnienia. Dostępny jest również pakiet react-native-bridge-spy do monitorowania ruchu.

Kiedy warto przejść z Bridge na Turbo Module?

Zaleca się przejście przy projektach wymagających wysokiej wydajności lub przy tworzeniu nowych aplikacji na React Native 0.76+. Dla istniejących projektów migracja może być stopniowa — obie architektury działają równolegle.

Podsumowanie

  • Bridge — asynchroniczny mechanizm komunikacji między JavaScript a kodem natywnym React Native, oparty na serializacji JSON.
  • MessageQueue zarządza kolejką wiadomości, grupując wywołania w partie w celu zmniejszenia narzutu.
  • Serializacja tworzy opóźnienie 30–50 ms przy przesyłaniu dużych tablic danych przez Bridge.
  • Ograniczenia architektury obejmują brak wywołań synchronicznych i wysokie zużycie pamięci przy częstych wiadomościach.
  • Nowa architektura React Native zastępuje Bridge przez JSI i Turbo Module, zapewniając bezpośredni dostęp bez serializacji.
  • Kompatybilność — Bridge działa w React Native do 0.72+, a w wersjach 0.73+ dostępna jest równoległa praca dwóch architektur.
  • Wybór — dla nowych projektów preferowana jest nowa architektura; istniejące projekty migrują stopniowo.

Opracujemy aplikację mobilną pod klucz

IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.

Omów projekt

Przeczytaj również