JSI: шта је то, принцип рада и архитектура

Аутор: IT Sectr Објављено: 2026-06-04 Време читања: 10 мин

JSI (JavaScript Interface) — је програмски слој у React Native који пружа директан синхрони приступ из JavaScript-а ка C++ објектима и функцијама, замењујући асинхрони JSON мост Bridge. За разлику од претходника, JSI омогућуће позивање нативних метода без серијализације порука и преношење референци на C++ објекте директно у JS окружење. Према подацима React Native Team (2025), JSI обезбеђује до 10 пута убрзања интеракције JS-а са нативним кодом у сценаријима са интензивном разменом података.

Главно

  • JSI — JavaScript Interface, који омогућује синхрони приступ из JS-а ка нативном C++ коду
  • Директан приступ елиминише потребу за серијализацијом у JSON и асинхроним редом порука
  • Перформансе интеракције JS-а и нативног кода расте 5–10 пута
  • Архитектура JSI је основа Fabric-а и TurboModules у новој архитектури React Native
  • C++ интеграција омогућује повезивање произвољних C++ библиотека без нативних омотача

Шта је JSI?

JSI (JavaScript Interface) — је C++ слој који пружа JavaScript погонском дону (Hermes, JavaScriptCore, V8) могућност да директно приступа C++ објектима, функцијама и меморији. За разлику од Bridge-а, који је серијализовао позиве у JSON и преносио их кроз асинхрони ред, JSI омогућује JS коду да синхроно позива C++ методе и добије резултат одмах.

JSI је представљена у React Native 0.64 као део нове архитектуре (New Architecture). Основни циљ је био да се елиминише уско грло које је био Bridge: свака интеракција између JS-а и нативног кода трошила време на серијализацију, десеријализацију и преношење кроз ред порука. JSI решава овај проблем пружајући JS погонском дону директан приступ C++ објектима путем омотача који имплементирају интерфејс jsi::Value, jsi::Object и jsi::Function.

JSI није замена Bridge-а „један на један“ — то је принципијелно другачији приступ интеграцији. Bridge је радио као поштанско сандуче: JS је слао поруку, она је прошла кроз ред, нативна страна је обрадила и послала одговор. JSI ради као показивач: JS добија референцу на C++ објекат и може да позива његове методе синхроно, као обичне JS функције. То је кључна разлика у архитектури интеракције два окружења.

Историја настанка

Потреба за JSI произашла је из ограничења оригиналног Bridge-а, постављеног у React Native 2015. Са порастом популарности фрејмворка и усложњавањем апликација, проблем перформанси је постао очигледан: сваки позив нативног модула захтевао је најмање 3–5 ms за серијализацију. За једноставне операције, као што је читање вредности сензора или добијање величине екрана, то је било прихватљиво, али за анимације, рад са графиком и проточну обраду података — критично. Тим React Native је започео рад на новој архитектури 2019. године, а JSI је постала њен фундамент.

Подршка JavaScript погонских донова

JSI је дизајнирана као апстракција над JavaScript погонским доновима. Пружа јединствени C++ API који се имплементира за сваки конкретан погонски дон: Hermes, JavaScriptCore (iOS), V8 (Android). То значи да се програмер не мора бринути о разликама између погонских донова — Fabric и TurboModules раде исто без обзира на то који JS погонски дон се користи.

Како ради JSI?

У основи JSI је концепт Host Objects — C++ објеката који се извозе у JS окружење као нативни JS објекти. Када JS код приступа својству или методи таквог објекта, JSI пресреће позив и прослеђује га одговарајућој C++ методи. То се дешава синхроно, у истој нити, без пребацивања контекста и без алокације меморије за JSON низку.

Сваки Host Object имплементира интерфејс jsi::HostObject са методама get, set и getPropertyNames. JS погонски дон позива ове методе при сваком приступу својствима објекта. На пример, када се позове NativeModule.someMethod() у JS-у, JSI претвара овај позив у C++ позив одговарајуће методе Host Object-а. Повратна вредност се преноси натраг у JS као jsi::Value — генерализовани тип који може да представља број, низку, булеанску вредност, објекат или undefined.

Важна карактеристика JSI је одсуство реда порука. Bridge је користио асинхрони ред: JS је слао захтев, прешао на друге задатке, нативна страна је обрадила захтев, и резултат се враћао кроз callback. JSI ради синхроно: ако JS позива методу нативног модула путем JSI, извршавање JS кода се паузира до добијања резултата. То поједностављује логику (није потребно чекати callback-е) и елиминише race conditions, али захтева опрезност — дуги синхрони позиви блокирају JS нит.

Животни циклус JSI вредности

Вредности креиране кроз JSI живе у извршном окружењу JS погонског дона и нъма управља сакупљач отпада. Када C++ код креира jsi::String или jsi::Object и враћа га у JS, окружење аутоматски управља меморијом. Ако C++ код жели да сачува референцу на JS вредност између позива, користи jsi::Value::getWeak() или глобални jsi::Object::setProperty са чувањем референце на коренском објекту runtime-а. То спречава прерано уклањање од стране сакупљача отпада.

Сигурност нити

JSI није подразумевано сигурна за нити. Сви JSI позиви метода морају долазити из нити у којој се извршава JS (обично је то JS нит React Native). Ако нативни модул покреће посао рад у засебној нити, резултат се мора вратити натраг кроз JS нит позивом runOnJS из TurboModules. Ово ограничење је цена за синхроност и одсуство серијализације.

JSI vs Bridge: поређење

Разлика између JSI и Bridge-а је фундаменталног карактера и утиче на све аспекте интеракције JS-а са нативним кодом. Bridge је био асинхрон, серијализовао је податке у JSON и користио ред порука; JSI је синхрон, ради са нативним референцама и не захтева серијализацију.

ПараметарBridgeJSI
Модел позиваАсинхрони редСинхрони директни позив
СеријализацијаJSON (серијализација + десеријализација)Нема (директне референце на C++ објекте)
Кашњење3–10 ms по позиву0.1–0.5 ms по позиву
ТипизацијаДинамичка (путем JSON-а)Статичка (путем Codegen-а)
C++ интеграцијаСамо кроз нативне модуле (Java/ObjC)Директна, без посредника
НитПосебна нативна нитJS нит (синхроно)

Према подацима React Native Team, миграција са Bridge-а на JSI у Facebook Marketplace апликацији скратила је време покретања за 35% и смањила потрошњу меморије за 20% захваљујући елиминацији дуплирања података између JS и нативне стране.

Када је Bridge био потребан

Bridge није био „грешка“ — био је архитектурно решење оправдано у тренутку стварања React Native 2015. године. Нативно програмирање за двије платформе са различитим језицима захтевало је универзални формат размене. JSON као формат серијализације био је доступан на свим платформама и омогућио је ујединачавање интеракције. Проблем се појавио касније, када је React Native почео да се користи за сложене апликације са хиљадама позива нативних модула у секунди.

Уназад компатибилност

React Native задржава уназад компатибилност: нативни модули написани за Bridge настављају да раде у новој архитектури кроз слој компатибилности. Међутим, за нове модуле препоручује се непосредно коришчење JSI кроз TurboModules. Миграција постојећих модула подразумева замену протокола интеракције без промене пословне логике самог модула.

JSI у архитектури React Native

JSI је фундаментални слој на којем су изграђени сви компоненти нове архитектуре React Native. Без JSI-а није могућ рад ни Fabric (нови рендерер) ни TurboModules (оптимизовани нативни модули). JSI обезбеђује јединствени начин интеракције JS-а са C++-ом на свим нивоима.

Fabric и JSI

Fabric — нови React Native рендерер који користи JSI за синхрони приступ C++ UI представама. У старој архитектури, рендеровање је ишло кроз Bridge: JS је креирао React елементе, серијализовао их у JSON, слао кроз Bridge, нативна страна је десеријализовала и креирала UI. Fabric путем JSI-а креира C++ Shadow Tree објекте директно из JS-а, синхроно израчунава Layout путем Yoga-е и преноси готове оквире нативном рендереру — без иједне серијализације.

TurboModules и JSI

TurboModules — је еволуција нативних React Native модула. Уместо регистровања модула у Bridge-у и позивања његових метода путем JSON-а, TurboModules користи JSI за лењиво учитавање и директно позивање. Када JS код први пут приступа модулу, JSI креира Host Object — он учитава нативни модул и пружа његове методе као C++ функције. Лењиво учитавање значи да модул не троши меморију до првог коришчења — то је нарочито важно за апликације са десетинама нативних модула, од којих се многи користе само на одређеним екранима.

Кодогенерација кроз JSI

За рад са JSI у новој архитектури користи се Codegen — алат који генерише C++ омотаче из JavaScript спецификација. Програмер описује интерфејс нативног модула у TypeScript или Flow, а Codegen генерише C++ код који имплементира Host Object компатибилан са JSI. То аутоматизује рутински посао и гарантује да су типови на JS и C++ страни синхронизовани.

Примери кода са JSI

Размотримо како изгледа рад са JSI у пракси. У овом примјеру креира се једноставна C++ класа која се извози у JS путем JSI-а, и њен метод се позива из JavaScript кода React Native.

cpp
// Calculator.h — C++ заглавље класе доступно из JS-а
class Calculator {
public:
    double add(double a, double b) { return a + b; }
    double multiply(double a, double b) { return a * b; }
};

Класа Calculator садржи двије аритметичке методе. Морамо је учинити го доступним из JS-а. За то креирамо Host Object који омотава Calculator и пружа његове методе кроз JSI.

cpp
// CalculatorHostObject.cpp — имплементација JSI омотача
class CalculatorHostObject : public jsi::HostObject {
private:
    Calculator calc;

public:
    jsi::Value get(jsi::Runtime& runtime,
        const jsi::PropNameID& name) override {
        auto propName = name.utf8(runtime);

        if (propName == "add") {
            return jsi::Function::createFromHostFunction(
                runtime, name, 2,
                [this](jsi::Runtime& runtime,
                    const jsi::Value& thisVal,
                    const jsi::Value* args,
                    size_t count) -> jsi::Value {
                    return jsi::Value(calc.add(
                        args[0].asNumber(),
                        args[1].asNumber()));
                });
        }
        return jsi::Value::undefined();
    }
};

У овом коду, метода get се позива сваки пут када JS приступа својству објекта. Ако је назив својства „add“, враћа се C++ функција која прима два аргумента из JS-а и позива calc.add(). Вредност се враћа као jsi::Value — JSI аутоматски конвертује double у JS број.

Позив из JavaScript-а

Након регистрације Host Object-а у JS окружењу, позив изгледа као обична JS функција. Сви типови се провјавају у фази кодогенерације, што елиминише грешке неподударања типова током извршавања.

js
// JavaScript — позивање C++ калкулатора путем JSI-а
import { Calculator } from 'react-native-calculator'

const result = Calculator.add(5, 3)
console.log(result) // 8 — синхроно, без кашњења

const product = Calculator.multiply(4, 2.5)
console.log(product) // 10 — одмах резултат

Обратите пажњу: резултат се враћа одмах, без Promise, без await, без callback-а. То је синхрони позив који је био немогућ у Bridge архитектури. За дуготрајне операције (читање датотеке, мрежни захтев) треба користити асинхроне обрасце — JSI не елиминише потребу за позадинским нитима за тешке задатке.

У пракси, већина програмера не пише JSI Host Objects ручно — овај посао обавља Codegen, који генерише C++ омотаче на основу TypeScript спецификација. Ипак, разумевање како JSI ради испод покропца је неопходно за ефикасно дебагирање перформанси и при креирању сложених нативних модула који захтевају директан приступ C++ библиотекама (Skia, FFmpeg, OpenCV).

Често постављана питања

По чему се JSI разликује од Bridge-а у React Native?

Bridge ради асинхроно кроз JSON серијализацију и ред порука — сваки позив захтева 3–10 ms за конверзију података. JSI пружа синхрони директан приступ C++ објектима без серијализације, смањујући кашњење на 0.1–0.5 ms. JSI такође подржава преношење референци на објекте, а не њихових копија.

Да ли JSI подржава све JavaScript погонске донове?

Да, JSI пружа јединствени C++ API који је имплементиран за Hermes (подразумевано у React Native), JavaScriptCore (iOS) и V8 (Android). Програмер не мора да пише различит код за различите погонске донове — Fabric и TurboModules раде исто на свим подржаним погонским доновима.

Могу ли се стари нативни модули користити са JSI?

Да, React Native пружа слој уназад компатибилности. Нативни модули написани за Bridge настављају да раде у новој архитектури. Ипак, препоручује се да се мигрирају на TurboModules ради предности JSI-а — лењивог учитавања и синхроних позива.

Да ли JSI захтева знање C++?

За свакодневни развој — не. TypeScript спецификације нативних модула се аутоматски компилирају у C++ омотаче путем Codegen-а. Знање C++ је потребно само при креирању сопствених C++ библиотека или при дебагирању перформансе JSI-а на нивоу runtime-а.

Које проблеме JSI решава?

JSI решава три кључна проблема Bridge-а: високу кашњење због JSON серијализације, непостојање синхроних позива и немогућност преношења сложених објеката путем референце. JSI такође омогућује директну интеграцију C++ библиотека, без Java или Objective-C прослоја.

Закључак

  • JSI (JavaScript Interface) — технологија директног синхроног приступа из JavaScript-а ка C++ објектима у React Native
  • Архитектура JSI се заснива на Host Objects — C++ објектима који се извозе у JS као нативни JS објекти
  • Перформансе позива кроз JSI је 10–50 пута већи него кроз Bridge захваљујући одсуству серијализације
  • Fabric и TurboModules — кључне компоненте нове архитектуре React Native изграђене на JSI-у
  • Синхроност JSI-а поједностављује логику кода, али захтева опрезност код дуготрајних операција
  • C++ интеграција омогућује повезивање било којих нативних библиотека без платформских омотача
  • Користите JSI за високоперформансне нативне модуле и мигрирајте постојеће са Bridge-а

Развићемо мобилну апликацију под кључ

IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.

Разговарајте о пројекту

Прочитајте такође