Bridge в React Native — що це, принцип роботи та взаємодія

Автор: IT Sectr Опубліковано: 2026-06-03 Час читання: 9 хв

Bridge — це архітектурний компонент React Native, що забезпечує асинхронну комунікацію між JavaScript-потоком та нативним середовищем iOS та Android. Він передає серіалізовані JSON-повідомлення через чергу, дозволяючи викликати нативні API з JS-коду. За даними Meta, 2024, Bridge залишається основою існуючих додатків, хоча програє за продуктивністю новій архітектурі на JSI.

Головне

  • Bridge — асинхронний канал зв’язку між JavaScript та нативним кодом в React Native.
  • Серіалізація — всі дані перетворюються в JSON перед передачею, що створює накладні витрати.
  • Асинхронність — повідомлення передаються через чергу, тому JS не блокує нативний потік.
  • Обмеження — Bridge не підходить для частих дрібних викликів через витрати на серіалізацію.
  • Заміна — в новій архітектурі React Native Bridge замінюється на JSI та Turbo Module.

Що таке Bridge в React Native?

Bridge — це ключовий архітектурний елемент React Native, що забезпечує двосторонню асинхронну комунікацію між JavaScript-потоком, де виконується бізнес-логіка додатка, та нативними потоками iOS та Android. З моменту випуску React Native у 2015 році, Bridge залишався єдиним способом взаємодії JS-коду з платформенними API — камера, геолокація, файлова система, сповіщення та інші нативні можливості.

Архітектура Bridge базується на принципі черги повідомлень (message queue). Коли JavaScript-код викликає нативний метод, запит серіалізується в JSON-рядок, поміщується в чергу та асинхронно відправляється на нативний бік. Нативний код обробляє запит, виконує відповідну операцію та відправляє результат назад через ту ж чергу в JS-потік. За даними звіту Meta на React Conf 2021, через Bridge проходить до 10 000 повідомлень на секунду в середньому додатку.

Основні потоки, що беруть участь у роботі Bridge: JavaScript Thread (виконання JS-коду), Native Thread (виконання нативних операцій) та Shadow Thread (розрахунок макету за допомогою Yoga). Кожен потік працює незалежно, що забезпечує чутливість UI — нативні анімації не блокуються JS-обчисленнями.

Як працює архітектура Bridge

Bridge використовує три ключові механізми для комунікації: MessageQueue, серіалізацію JSON та пакетування повідомлень (batching). MessageQueue — це внутрішній компонент React Native, який керує чергою викликів між JS та нативним боком. Кожен виклик нативного методу поміщується в чергу, серіалізується та відправляється пакетами для оптимізації продуктивності.

MessageQueue та серіалізація

MessageQueue працює за принципом пакетування: виклики нативних методів накопичуються та відправляються як одна група (пакет) кожні 5–15 мілісекунд. Це знижує накладні витрати на серіалізацію, оскільки кілька викликів упаковуються в один JSON-пакет. На нативному боці повідомлення десеріалізуються та розподіляються між відповідними модулями.

Реєстрація модулів

Нативні модулі реєструються автоматично через макроси або анотації. iOS використовує макрос RCT_EXPORT_MODULE, Android — анотацію @ReactMethod. React Native сканує зареєстровані модулі при запуску додатка та будує конфігураційну JSON-карту всіх доступних методів. Ця карта передається в JS-середовище, і JavaScript дізнається, які методи можна викликати.

Потік даних

Дані проходять такий шлях: JavaScript викликає NativeModules.CalendarModule.createCalendarEvent(). Метод серіалізується в JSON-повідомлення з ідентифікатором модуля, іменем методу та аргументами. Повідомлення потрапляє в MessageQueue. На нативному потоці повідомлення десеріалізується та передається відповідному модулю. Результат виконання серіалізується назад та відправляється в JS-потік як Promise або callback.

js
            // Виклик нативного модуля з JavaScript через Bridge
import { NativeModules } from 'react-native';

const CalendarModule = NativeModules.CalendarModule;

CalendarModule.createCalendarEvent('Test Event', 'Office')
  .then(eventId => {
    console.log('Створено подію з ід:', eventId);
  })
  .catch(error => {
    console.error('Не вдалося:', error);
  });

На нативному боці iOS модуль виглядає як Objective-C клас з макросом RCT_EXPORT_MODULE. Метод експортується макросом RCT_EXPORT_METHOD, і React Native автоматично реєструє його в Bridge. Аргументи передаються за позицією і мають відповідати підтримуваним типам JSON: NSString, NSNumber, NSArray, NSDictionary, BOOL.

objective-c
            // Реєстрація iOS нативного модуля в 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

Bridge має ряд фундаментальних обмежень продуктивності. Головне з них — обов’язкова асинхронність та серіалізація. Кожен виклик нативного методу перетворює дані в JSON-рядок, що додає затримку та споживає пам’ять. Для операцій з великими обсягами даних, таких як обробка зображень або робота з відео, це стає вузьким місцем.

Витрати на серіалізацію

Серіалізація та десеріалізація JSON споживають час CPU та пам’ять. Кожне повідомлення має бути перетворене в рядок на JS-боці, передане через місток та розібране на нативному боці. За даними тестів Callstack (2022), серіалізація масиву з 10 000 чисел через Bridge займає близько 30–50 мілісекунд, що неприйнятно для високочастотних викликів.

Обмеження за розміром повідомлень

Bridge не оптимізований для передачі великих бінарних даних. Фотографії, аудіофайли та відеопотоки потребують альтернативних підходів — наприклад, запису файлу на диск та передачі шляху у вигляді рядка. Це створює додаткові накладні витрати на читання та запис файлової системи.

  • Асинхронність — Bridge не підтримує синхронні виклики, що ускладнює сценарії, що вимагають миттієвої відповіді.
  • Пам’ять — кожне повідомлення зберігається в черзі до обробки, що може призвести до зростання споживання пам’яті.
  • Налагодження — відстеження повідомлень в Bridge ускладнене, оскільки ланцюжок викликів розривається між потоками.

Усвідомлення цих обмежень призвело команду Meta до розробки нової архітектури React Native, в якій Bridge замінюється на JSI (JavaScript Interface) та Turbo Module. JSI дозволяє викликати нативні методи безпосередньо, без серіалізації, що усуває головний недолік Bridge.

Bridge vs Turbo Module: порівняння

Порівняння Bridge та Turbo Module показує фундаментальні відмінності в архітектурних підходах. Bridge використовує асинхронну чергу повідомлень з серіалізацією JSON, тоді як Turbo Module працює через JSI — прямий інтерфейс між JavaScript та C++, який дозволяє синхронно викликати нативні методи без перетворення даних.

ХарактеристикаBridgeTurbo Module
Тип викликуАсинхроннийСинхронний та асинхронний
СеріалізаціяJSON на кожен викликJSI-об’єкти без копіювання
ПродуктивністьСередняВисока
ТипізаціяДинамічнаСтатична (Codegen)
ЗавантаженняВсі модулі при стартіЛеніве (за потреби)

Вибір між Bridge та Turbo Module залежить від версії React Native. Для проектів на React Native 0.72 та старших, Bridge залишається основним механізмом. Починаючи з React Native 0.73, Metro та нова архітектура підтримуються паралельно, що дозволяє поступову міграцію. Повний перехід на Turbo Module вимагає оновлення до React Native 0.76+ та увімкнення нової архітектури в конфігурації.

Приклад налаштування Native Module через Bridge

Розглянемо повний цикл створення та використання Native Module через Bridge на прикладі модуля календаря. Модуль створюватиме подію та повертатиме її ідентифікатор. Цей приклад охоплює налаштування для обох платформ — iOS та Android.

Android модуль

На Android Native Module створюється як Java-клас, що успадковує ReactContextBaseJavaModule. Анотація @ReactMethod експортує метод в Bridge. Для Promise використовується інтерфейс Promise з 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());
        }
    }
}

Реєстрація та використання

Модуль реєструється через @ReactModule або вручну в пакеті додатка. React Native автоматично виявляє його та додає в Bridge. Після реєстрації модуль доступний з JavaScript через 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();
    }
}

Важливо відмітити, що Bridge вимагає перезапуску додатка при додаванні нових модулів, оскільки конфігураційна карта будується лише одноразово під час ініціалізації. Це відрізняє його від Turbo Module, який завантажується леніво та підтримує гаряче перезавантаження модулів без перезапуску.

Часті запитання

Чим Bridge відрізняється від прямої передачі даних?

Bridge завжди використовує асинхронну чергу та JSON-серіалізацію, тоді як пряма передача через JSI працює синхронно та без копіювання даних. Bridge створює затримку на серіалізацію, але забезпечує ізоляцію потоків.

Чи можна викликати методи синхронно через Bridge?

Ні, Bridge підтримує лише асинхронні виклики. Для синхронної взаємодії потрібна нова архітектура з JSI та Turbo Module. Це одне з ключових обмежень, яке було вирішено в React Native 0.76+.

Які типи даних підтримує Bridge?

Bridge підтримує типи, що серіалізуються в JSON: рядки, числа, булеві значення, масиви, словники (об’єкти). Бінарні дані, такі як зображення, необхідно передавати через файлову систему або base64-кодування.

Як виміряти продуктивність Bridge?

Для вимірювання використовуйте React DevTools та профілювач React Native. Вкладка Performance показує кількість повідомлень в черзі Bridge та затримки. Також доступний пакет react-native-bridge-spy для моніторингу трафіку.

Коли варто переходити з Bridge на Turbo Module?

Рекомендується переходити для проектів, вимогливих до продуктивності, або при створенні нових додатків на React Native 0.76+. Для існуючих проектів міграція може бути поступовою — обидві архітектури працюють паралельно.

Підсумки

  • Bridge — асинхронний механізм комунікації між JavaScript та нативним кодом React Native, заснований на серіалізації JSON.
  • MessageQueue керує чергою повідомлень, групуючи виклики в пакети для зниження накладних витрат.
  • Серіалізація створює затримку 30–50 мс при передачі великих масивів даних через Bridge.
  • Обмеження архітектури включають відсутність синхронних викликів та високе споживання пам’яті при частих повідомленнях.
  • Нова архітектура React Native замінює Bridge на JSI та Turbo Module, забезпечуючи прямий доступ без серіалізації.
  • Сумісність — Bridge продовжує працювати в React Native до 0.72+, а в версіях 0.73+ доступна паралельна робота обох архітектур.
  • Вибір — для нових проектів нова архітектура є кращою; існуючі проекти мігрують поступово.

Ми розробимо мобільний застосунок під ключ

IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.

Обговорити проект

Читайте також