JSI: mi ez, működési elv és architektúra

Szerző: IT Sectr Megjelenés: 2026-06-04 Olvasási idő: 10 perc

JSI (JavaScript Interface) — egy szoftverréteg a React Native-ban, amely közvetlen szinkron hozzáférést biztosít JavaScript-ből C++ objektumokhoz és függvényekhez, felváltva az aszinkron JSON hidat, a Bridge-t. Elődjétől eltérően, a JSI lehetővé teszi natív metódusok meghívását üzenetek szerializálása nélkül, és C++ objektumokra mutató referenciák közvetlen átadását a JS környezetbe. A React Native Team (2025) adatai szerint a JSI akár 10-szeres gyorsulást is biztosít a JS és a natív kód közötti interakcióban intenzív adatcserével járó forgatókönyvekben.

Főbb pontok

  • JSI — JavaScript Interface, amely szinkron hozzáférést biztosít JS-ből a natív C++ kódhoz
  • Közvetlen hozzáférés megszünteti a JSON szerializálás és az aszinkron üzenetsor szükségességét
  • Teljesítmény a JS és a natív kód interakciója 5–10-szeresére nő
  • Architektúra a JSI képezi a Fabric és a TurboModules alapját az új React Native architektúrában
  • C++ integráció lehetővé teszi tetszőleges C++ könyvtárak csatlakoztatását natív burkolók nélkül

Mi az a JSI?

JSI (JavaScript Interface) — egy C++ réteg, amely lehetővé teszi a JavaScript-motor (Hermes, JavaScriptCore, V8) számára, hogy közvetlenül hozzáférjen C++ objektumokhoz, függvényekhez és memóriához. A Bridge-től eltérően, amely a hívásokat JSON-ba szerializálta és egy aszinkron soron keresztül továbbította, a JSI lehetővé teszi a JS kódnak, hogy szinkron módon hívjon C++ metódusokat és azonnal megkapja az eredményt.

A JSI-t a React Native 0.64-ben vezették be az új architektúra (New Architecture) részeként. A fő cél a Bridge által okozott szűk keresztmetszet megszüntetése volt: a JS és a natív kód közötti minden interakció időt vett igénybe a szerializálásra, deszerializálásra és az üzenetsoron keresztüli továbbításra. JSI megoldja ezt a problémát azzal, hogy közvetlen hozzáférést biztosít a JS motornak a C++ objektumokhoz olyan burkolókon keresztül, amelyek megvalósítják a jsi::Value, jsi::Object és jsi::Function interfészt.

A JSI nem „egy-az-egyben” helyettesítője a Bridge-nek — ez egy alapvetően más megközelítés az integrációhoz. A Bridge úgy működött, mint egy postaláda: a JS elküldött egy üzenetet, az átment a soron, a natív oldal feldolgozta és választ küldött. A JSI úgy működik, mint egy mutató: a JS kap egy referenciát egy C++ objektumra, és szinkron módon hívhatja annak metódusait, mint a szokásos JS függvényeket. Ez az alapvető különbség a két környezet interakciójának architektúrájában.

Létrejöttének története

A JSI iránti igény az eredeti Bridge korlátaiból fakadt, amelyet a 2015-ös React Native-ban hoztak létre. Ahogy a framework növekvő népszerűséggel és az alkalmazások egyre összetettebbé váltak, a teljesítményprobléma nyilvánvalóvá vált: minden natív modulhívásnak legalább 3–5 ms-ra volt szüksége a szerializáláshoz. Egyszerű műveletekhez, mint egy szenzor értékének olvasása vagy a képernyőméret lekérése, ez elfogadható volt, de animációkhoz, grafikai munkához és adatfolyam-feldolgozáshoz — kritikus. A React Native csapat 2019-ben kezdte meg az új architektúra munkálatait, és a JSI vált annak alapjává.

JavaScript motorok támogatása

A JSI a JavaScript motorok feletti absztrakcióként lett tervezve. Egységes C++ API-t biztosít, amely minden konkrét motorhoz implementálva van: Hermes, JavaScriptCore (iOS), V8 (Android). Ez azt jelenti, hogy a fejlesztőnek nem kell aggódnia a motorok közötti különbségek miatt — a Fabric és a TurboModules ugyanúgy működik, függetlenül attól, hogy melyik JS motort használják.

Hogyan működik a JSI?

A JSI alapjában a Host Objects koncepciója áll — C++ objektumok, amelyek natív JS objektumokként exportálódnak a JS környezetbe. Amikor a JS kód hozzáfér egy ilyen objektum tulajdonságához vagy metódusához, a JSI elfogja a hívást és továbbítja a megfelelő C++ metódushoz. Ez szinkron módon, ugyanabban a szálban történik, kontextusváltás és JSON karakterlánc memóriafoglalása nélkül.

Minden Host Object megvalósítja a jsi::HostObject interfészt a get, set és getPropertyNames metódusokkal. A JS motor ezeket a metódusokat hívja meg az objektum tulajdonságainak minden elérésekor. Például, amikor a NativeModule.someMethod() meghívásra kerül JS-ben, a JSI ezt a hívást a Host Object megfelelő metódusának C++ hívásává alakítja. A visszaadott érték jsi::Value-ként kerül vissza JS-be — egy általánosított típus, amely egy számot, karakterláncot, logikai értéket, objektumot vagy undefined-et képviselhet.

A JSI egyik fontos jellemzője az üzenetsor hiánya. A Bridge aszinkron sort használt: a JS elküldött egy kérést, átváltott más feladatokra, a natív oldal feldolgozta a kérést, és az eredmény egy callbacken keresztül érkezett vissza. A JSI szinkron módon működik: ha a JS egy natív modul metódusát hívja meg a JSI-n keresztül, a JS kód végrehajtása felfüggesztődik az eredmény megérkezéséig. Ez leegyszerűsíti a logikát (nem kell várni a callbackekre) és kiküszöböli a versenyfeltételeket, de óvatosságot igényel — a hosszú szinkron hívások blokkolják a JS szálat.

A JSI értékek életciklusa

A JSI-n keresztül létrehozott értékek a JS motor futási környezetében élnek, és a szemétgyűjtő kezeli őket. Amikor a C++ kód létrehoz egy jsi::String vagy jsi::Object objektumot és visszaadja JS-be, a környezet automatikusan kezeli a memóriát. Ha a C++ kód meg akar tartani egy referenciát egy JS értékre a hívások között, akkor a jsi::Value::getWeak() vagy a globális jsi::Object::setProperty használja a referencia megtartásával a runtime gyökér objektumán. Ez megakadályozza a szemétgyűjtő általi idő előtti eltávolítást.

Szálbiztonság

A JSI alapértelmezésben nem szálbiztos. Minden JSI metódushívásnak abból a szálból kell származnia, amelyben a JS fut (általában ez a React Native JS szála). Ha egy natív modul háttérmunkát indít egy külön szálban, az eredményt a JS szálon keresztül kell visszaküldeni a TurboModules runOnJS hívásával. Ez a korlátozás a szinkronitás és a szerializálás hiányának ára.

JSI vs Bridge: összehasonlítás

A JSI és a Bridge közötti különbség alapvető jellegű, és érinti a JS és a natív kód közötti interakció minden aspektusát. A Bridge aszinkron volt, szerializálta az adatokat JSON-ba és üzenetsort használt; a JSI szinkron, natív referenciákkal dolgozik és nem igényel szerializálást.

ParaméterBridgeJSI
Hívási modellAszinkron sorSzinkron közvetlen hívás
SzerializálásJSON (szerializálás + deszerializálás)Nincs (közvetlen referenciák C++ objektumokra)
Késleltetés3–10 ms hívásonként0.1–0.5 ms hívásonként
TípusosságDinamikus (JSON-en keresztül)Statikus (Codegenen keresztül)
C++ integrációCsak natív modulokon keresztül (Java/ObjC)Közvetlen, közvetítők nélkül
SzálKülön natív szálJS szál (szinkron)

A React Native Team adatai szerint a Bridge-ről JSI-re való migráció a Facebook Marketplace alkalmazásban 35%-kal csökkentette az indítási időt és 20%-kal csökkentette a memóriafogyasztást az adatok JS és a natív oldal közötti duplikálódásának megszüntetésével.

Mikor volt szükséges a Bridge

A Bridge nem „hiba” volt — egy építészeti döntés volt, amely a React Native 2015-ös létrehozásakor indokolt volt. A natív fejlesztés két különböző platformhoz, különböző nyelvekkel, univerzális csereformátumot igényelt. JSON szerializálási formátumként minden platformon elérhető volt, és lehetővé tette az interakció egységesítését. A probléma később jelentkezett, amikor a React Native-t összetett alkalmazásokhoz kezdték használni, másodpercenként ezreket meghaladó natív modulhívással.

Visszafelé kompatibilitás

A React Native megtartja a visszafelé kompatibilitást: a Bridge-hez írt natív modulok továbbra is működnek az új architektúrában egy kompatibilitási rétegen keresztül. Az új modulokhoz azonban ajánlott azonnal a JSI használata a TurboModules-on keresztül. A meglévő modulok migrációja az interakciós protokoll cseréjéből áll anélkül, hogy a modul üzleti logikáját megváltoztatnák.

JSI a React Native architektúrában

A JSI az az alapvető réteg, amelyre a React Native új architektúrájának összes komponense épül. JSI nélkül sem a Fabric (új renderelő), sem a TurboModules (optimalizált natív modulok) nem működhetne. A JSI egységes módot biztosít a JS és a C++ közötti interakcióra minden szinten.

Fabric és JSI

Fabric — az új React Native renderelő, amely a JSI-t használja a C++ UI megjelenítések szinkron eléréséhez. A régi architektúrában a renderelés a Bridge-en keresztül történt: a JS létrehozta a React elemeket, szerializálta őket JSON-ba, elküldte a Bridge-en keresztül, a natív oldal deszerializálta és létrehozta a UI-t. A Fabric a JSI-n keresztül közvetlenül JS-ből hozza létre a C++ Shadow Tree objektumokat, szinkron módon számolja ki a Layout-ot a Yoga segítségével, és továbbítja a kész kereteket a natív renderelőnek — egyetlen szerializálás nélkül.

TurboModules és JSI

TurboModules — a natív React Native modulok evolúciója. Ahelyett, hogy a modult a Bridge-ben regisztrálnák és a metódusait JSON-on keresztül hívnák, a TurboModules a JSI-t használja lusta betöltéshez és közvetlen híváshoz. Amikor a JS kód először hozzáfér egy modulhoz, a JSI létrehoz egy Host Objectet — ez betölti a natív modult és annak metódusait C++ függvényekként kínálja. Lusta betöltés azt jelenti, hogy a modul nem fogyaszt memóriát az első használatig — ez különösen fontos olyan alkalmazásokban, amelyek tucatnyi natív modult tartalmaznak, amelyek közül sokat csak bizonyos képernyőkön használnak.

Kódgenerálás JSI-n keresztül

A JSI-vel való munkához az új architektúrában a Codegen-t használják — egy eszközt, amely JavaScript specifikációkból generál C++ burkolókat. A fejlesztő leírja a natív modul interfészét TypeScript vagy Flow nyelven, és a Codegen C++ kódot generál, amely egy JSI-kompatibilis Host Objectet valósít meg. Ez automatizálja a rutinmunkát és garantálja, hogy a típusok a JS és a C++ oldalon szinkronizálva legyenek.

Kódpéldák JSI-vel

Nézzük meg, hogyan néz ki a JSI-vel való munka a gyakorlatban. Ebben a példában létrehozunk egy egyszerű C++ osztályt, amely JSI-n keresztül exportálódik JS-be, és annak metódusát a React Native JavaScript kódjából hívjuk meg.

cpp
// Calculator.h — C++ osztály fejléc, elérhető JS-ből
class Calculator {
public:
    double add(double a, double b) { return a + b; }
    double multiply(double a, double b) { return a * b; }
};

A Calculator osztály két aritmetikai metódust tartalmaz. El kell érnünk, hogy JS-ből is elérhető legyen. Ehhez létrehozunk egy Host Objectet, amely becsomagolja a Calculator-t és annak metódusait JSI-n keresztül kínálja.

cpp
// CalculatorHostObject.cpp — JSI burkoló implementáció
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();
    }
};

Ebben a kódban a get metódust minden alkalommal meghívja a rendszer, amikor a JS hozzáfér az objektum tulajdonságához. Ha a tulajdonság neve „összeadás”, akkor egy C++ függvény kerül visszaadásra, amely két argumentumot fogad JS-ből és meghívja a calc.add()-ot. Az érték jsi::Value-ként kerül visszaadásra — a JSI automatikusan konvertálja a double-t JS számmá.

Hívás JavaScript-ből

Miután a Host Object regisztrálásra került a JS környezetben, a hívás egy szokásos JS függvényhez hasonlít. Minden típus ellenőrzésre kerül a kódgenerálás fázisában, ami kiküszöböli a típuseltérési hibákat futási időben.

js
// JavaScript — C++ számológép hívása JSI-n keresztül
import { Calculator } from 'react-native-calculator'

const result = Calculator.add(5, 3)
console.log(result) // 8 — szinkron, késleltetés nélkül

const product = Calculator.multiply(4, 2.5)
console.log(product) // 10 — azonnali eredmény

Figyelje meg: az eredmény azonnal, Promise, await és callbackek nélkül érkezik. Ez egy szinkron hívás, amely lehetetlen volt a Bridge architektúrában. Hosszó időt igénylő műveletekhez (fájl olvasása, hálózati kérés) aszinkron mintákat kell használni — a JSI nem szünteti meg a háttérszálak szükségességét a nehéz feladatokhoz.

A gyakorlatban a legtöbb fejlesztő nem ír JSI Host Objecteket kézzel — ezt a munkát a Codegen végzi, amely TypeScript specifikációk alapján generál C++ burkolókat. Azonban annak megértése, hogy a JSI hogyan működik a motorház alatt, elengedhetetlen a hatékony teljesítmény-hibakereséshez és az olyan összetett natív modulok létrehozásához, amelyek közvetlen hozzáférést igényelnek C++ könyvtárakhoz (Skia, FFmpeg, OpenCV).

Gyakran Ismételt Kérdések

Miben különbözik a JSI a Bridge-től a React Native-ban?

A Bridge aszinkron módon működik JSON szerializáláson és üzenetsoron keresztül — minden hívás 3–10 ms-ot igényel az adatkonverzióhoz. A JSI szinkron közvetlen hozzáférést biztosít a C++ objektumokhoz szerializálás nélkül, 0.1–0.5 ms-ra csökkentve a késleltetést. JSI támogatja az objektumok referenciáinak átadását is, nem a másolataikét.

Támogatja a JSI az összes JavaScript motort?

Igen, a JSI egységes C++ API-t biztosít, amely a Hermes (alapértelmezett a React Native-ban), a JavaScriptCore (iOS) és a V8 (Android) számára van implementálva. A fejlesztőnek nem kell különböző kódot írnia különböző motorokhoz — a Fabric és a TurboModules ugyanúgy működik az összes támogatott motoron.

Használhatóak a régi natív modulok a JSI-vel?

Igen, a React Native visszafelé kompatibilitási réteget biztosít. A Bridge-hez írt natív modulok továbbra is működnek az új architektúrában. Javasolt azonban ezek migrálása a TurboModules-ra a JSI előnyeinek — lusta betöltés és szinkron hívások — kihasználása érdekében.

Igényel-e a JSI C++ ismereteket?

A mindennapi fejlesztéshez — nem. A natív modulok TypeScript specifikációi automatikusan C++ burkolókká fordulnak a Codegen-en keresztül. C++ ismeretekre csak saját C++ könyvtárak létrehozásakor vagy a JSI teljesítményének futási idő szintű hibakeresésekor van szükség.

Milyen problémákat old meg a JSI?

A JSI három fő problémát old meg a Bridge-ben: a JSON szerializálás miatti magas késleltetést, a szinkron hívások hiányát és az összetett objektumok referencia útján történő átadásának lehetetlenségét. A JSI lehetővé teszi továbbá a C++ könyvtárak közvetlen integrációját, Java vagy Objective-C réteg nélkül.

Összefoglalás

  • JSI (JavaScript Interface) — technológia a JavaScript-ből a C++ objektumokhoz való közvetlen szinkron hozzáféréshez a React Native-ban
  • Architektúra A JSI a Host Objects-en alapul — C++ objektumokon, amelyek natív JS objektumokként exportálódnak JS-be
  • Teljesítmény A JSI-n keresztüli hívások 10–50-szer gyorsabbak, mint a Bridge-en keresztül a szerializálás hiánya miatt
  • Fabric és TurboModules — a JSI-re épülő új React Native architektúra kulcsfontosságú komponensei
  • Szinkronitás A JSI leegyszerűsíti a kód logikáját, de óvatosságra van szükség hosszú műveleteknél
  • C++ integráció Lehetővé teszi bármilyen natív könyvtár csatlakoztatását platform burkolók nélkül
  • Használja a JSI-t nagy teljesítményű natív modulokhoz és migrálja a meglévő Bridge modulokat

Kulcsrakész mobilalkalmazást fejlesztünk

Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.

Projekt megbeszélése

Olvassa el is