JSI: vad det är, funktionsprincip och arkitektur

Författare: IT Sectr Publicerad: 2026-06-04 Lästid: 10 min

JSI (JavaScript Interface) — är en programvarulager i React Native som ger direkt synkron åtkomst från JavaScript till C++-objekt och funktioner, och ersätter den asynkrona JSON-bryggan Bridge. Till skillnad från sin föregångare tillåter JSI anrop av nativa metoder utan serialisering av meddelanden och överföring av referenser till C++-objekt direkt till JS-miljön. Enligt uppgifter från React Native Team (2025), ger JSI upp till 10 gångers acceleration av JS-interaktion med nativ kod i scenarier med intensivt datautbyte.

Huvudsakliga

  • JSI — JavaScript Interface, som ger synkron åtkomst från JS till nativ C++-kod
  • Direkt åtkomst eliminerar behovet av serialisering till JSON och asynkron meddelandekö
  • Prestanda för interaktion mellan JS och nativ kod ökar 5–10 gånger
  • Arkitektur JSI ligger till grund för Fabric och TurboModules i den nya React Native-arkitekturen
  • C++-integration gör det möjligt att ansluta godtyckliga C++-bibliotek utan nativa omslag

Vad är JSI?

JSI (JavaScript Interface) — är ett C++-lager som ger JavaScript-motorn (Hermes, JavaScriptCore, V8) möjlighet att direkt komma åt C++-objekt, funktioner och minne. Till skillnad från Bridge, som serialiserade anrop till JSON och överförde dem via en asynkron kö, tillåter JSI JS-kod att synkront anropa C++-metoder och omedelbart få resultatet.

JSI introducerades i React Native 0.64 som en del av den nya arkitekturen (New Architecture). Huvudmålet var att eliminera flaskhalsen som Bridge utgjorde: varje interaktion mellan JS och nativ kod förbrukade tid på serialisering, deserialisering och överföring via meddelandekön. JSI löser detta problem genom att ge JS-motorn direkt åtkomst till C++-objekt via omslag som implementerar gränssnitten jsi::Value, jsi::Object och jsi::Function.

JSI är inte en „en-till-en”-ersättning för Bridge — det är ett fundamentalt annorlunda synsätt på integration. Bridge fungerade som en brevlåda: JS skickade ett meddelande, det gick genom kön, den nativa sidan bearbetade det och skickade ett svar. JSI fungerar som en pekare: JS får en referens till ett C++-objekt och kan anropa dess metoder synkront, precis som vanliga JS-funktioner. Detta är den grundläggande skillnaden i arkitekturen för interaktion mellan två miljöer.

Historik

Behovet av JSI uppstod på grund av begränsningarna hos den ursprungliga Bridge, som skapades i React Native 2015. I takt med att ramverkets popularitet ökade och applikationerna blev mer komplexa, blev prestandaproblemet uppenbart: varje anrop till en nativ modul krävde minst 3–5 ms för serialisering. För enkla operationer, som att läsa ett sensorvärde eller hämta skärmstorleken, var detta acceptabelt, men för animationer, grafikarbete och strömmande databehandling — kritiskt. React Native-teamet började arbeta på den nya arkitekturen 2019, och JSI blev dess grund.

Stöd för JavaScript-motorer

JSI är utformad som en abstraktion över JavaScript-motorer. Den tillhandahåller ett enhetligt C++-API som implementeras för varje specifik motor: Hermes, JavaScriptCore (iOS), V8 (Android). Detta innebär att utvecklaren inte behöver oroa sig för skillnader mellan motorer — Fabric och TurboModules fungerar på samma sätt oavsett vilken JS-motor som används.

Hur fungerar JSI?

Grunden för JSI är konceptet Host Objects — C++-objekt som exporteras till JS-miljön som nativa JS-objekt. När JS-kod når en egenskap eller metod hos ett sådant objekt, fångar JSI upp anropet och delegerar det till motsvarande C++-metod. Detta sker synkront, i samma tråd, utan kontextväxling och utan minnesallokering för en JSON-sträng.

Varje Host Object implementerar gränssnittet jsi::HostObject med metoderna get, set och getPropertyNames. JS-motorn anropar dessa metoder vid varje åtkomst till objektets egenskaper. Till exempel, vid anrop av NativeModule.someMethod() i JS, omvandlar JSI detta anrop till ett C++-anrop av motsvarande metod i Host Object. Returvärdet skickas tillbaka till JS som jsi::Value — en generaliserad typ som kan representera ett tal, en sträng, ett booleskt värde, ett objekt eller undefined.

En viktig egenskap hos JSI är frånvaron av meddelandekö. Bridge använde en asynkron kö: JS skickade en begäran, växlade till andra uppgifter, den nativa sidan bearbetade begäran och resultatet kom tillbaka via en callback. JSI fungerar synkront: om JS anropar en metod i en nativ modul via JSI, pausas exekveringen av JS-koden tills resultatet har erhållits. Detta förenklar logiken (man behöver inte vänta på callbacks) och eliminerar race conditions, men kräver försiktighet — långa synkrona anrop blockerar JS-tråden.

Livscykel för JSI-värden

Värden som skapas via JSI lever i JS-motorns runtime-miljö och hanteras av skräpinsamlaren. När C++-kod skapar ett jsi::String eller jsi::Object och returnerar det till JS, hanterar miljön automatiskt minnet. Om C++-kod vill behålla en referens till ett JS-värde mellan anrop, används jsi::Value::getWeak() eller global jsi::Object::setProperty med bevarande av referensen på runtime-objektets rot. Detta förhindrar förtidig borttagning av skräpinsamlaren.

Trådsäkerhet

JSI är inte standardmässigt trådsäker. Alla anrop av JSI-metoder måste komma från den tråd där JS exekveras (vanligtvis är detta React Native JS-tråd). Om en nativ modul startar bakgrundsarbete i en separat tråd, måste resultatet skickas tillbaka via JS-tråden med hjälp av anropet runOnJS från TurboModules. Denna begränsning är priset för synkronicitet och frånvaro av serialisering.

JSI vs Bridge: jämförelse

Skillnaden mellan JSI och Bridge är av grundläggande karaktär och påverkar alla aspekter av interaktionen mellan JS och nativ kod. Bridge var asynkron, serialiserade data till JSON och använde en meddelandekö; JSI är synkron, arbetar med nativa referenser och kräver ingen serialisering.

ParameterBridgeJSI
AnropsmodellAsynkron köSynkront direktanrop
SerialiseringJSON (serialisering + deserialisering)Ingen (direkta referenser till C++-objekt)
Fördröjning3–10 ms per anrop0.1–0.5 ms per anrop
TypningDynamisk (via JSON)Statisk (via Codegen)
C++-integrationEndast via nativa moduler (Java/ObjC)Direkt, utan mellanhänder
TrådSeparat nativ trådJS-tråd (synkront)

Enligt uppgifter från React Native Team, minskade migreringen från Bridge till JSI i Facebook Marketplace-appen starttiden med 35% och minskade minnesförbrukningen med 20% tack vare eliminering av dataduplicering mellan JS och den nativa sidan.

När Bridge var nödvändig

Bridge var inte ett „misstag” — det var ett arkitektoniskt beslut som var motiverat vid tiden för skapandet av React Native 2015. Native utveckling för två plattformar med olika språk krävde ett universellt utbytesformat. JSON som serialiseringsformat var tillgängligt på alla plattformar och möjliggjorde enhetliggörande av interaktionen. Problemet visade sig senare, när React Native började användas för komplexa applikationer med tusentals anrop till nativa moduler per sekund.

Bakåtkompatibilitet

React Native behåller bakåtkompatibilitet: nativa moduler skrivna för Bridge fortsätter att fungera i den nya arkitekturen genom ett kompatibilitetslager. För nya moduler rekommenderas dock att omedelbart använda JSI via TurboModules. Migrering av befintliga moduler består av att byta interaktionsprotokoll utan att ändra modulens affärslogik.

JSI i React Native-arkitekturen

JSI är det grundläggande lagret som alla komponenter i den nya React Native-arkitekturen är byggda på. Utan JSI skulle varken Fabric (den nya renderaren) eller TurboModules (optimerade nativa moduler) kunna fungera. JSI tillhandahåller ett enhetligt sätt för interaktion mellan JS och C++ på alla nivåer.

Fabric och JSI

Fabric — den nya React Native-renderaren som använder JSI för synkron åtkomst till C++-representationer av UI. I den gamla arkitekturen gick rendering via Bridge: JS skapade React-element, serialiserade dem till JSON, skickade via Bridge, den nativa sidan deserialiserade och skapade UI. Fabric skapar via JSI C++ Shadow Tree-objekt direkt från JS, beräknar synkront Layout via Yoga och överför färdiga ramar till den nativa renderaren — utan någon serialisering.

TurboModules och JSI

TurboModules — är evolutionen av React Native nativa moduler. Istället för att registrera modulen i Bridge och anropa dess metoder via JSON, använder TurboModules JSI för lat laddning och direkt anrop. När JS-kod första gången når en modul, skapar JSI ett Host Object — det laddar den nativa modulen och tillhandahåller dess metoder som C++-funktioner. Lat laddning innebär att modulen inte förbrukar minne förrän första användningen — detta är särskilt viktigt i applikationer med dussintals nativa moduler, varav många endast används på vissa skärmar.

Kodgenerering via JSI

För arbete med JSI i den nya arkitekturen används Codegen — ett verktyg som genererar C++-omslag från JavaScript-specifikationer. Utvecklaren beskriver gränssnittet för den nativa modulen i TypeScript eller Flow, och Codegen genererar C++-kod som implementerar en JSI-kompatibel Host Object. Detta automatiserar rutinarbete och garanterar att typerna på JS- och C++-sidan är synkroniserade.

Kodexempel med JSI

Låt oss se hur arbetet med JSI ser ut i praktiken. I detta exempel skapas en enkel C++-klass som exporteras till JS via JSI, och dess metod anropas från JavaScript-kod i React Native.

cpp
// Calculator.h — C++-klasshuvud tillgängligt från JS
class Calculator {
public:
    double add(double a, double b) { return a + b; }
    double multiply(double a, double b) { return a * b; }
};

Klassen Calculator innehåller två aritmetiska metoder. Vi måste göra den tillgänglig från JS. För detta skapar vi ett Host Object som omsluter Calculator och tillhandahåller dess metoder via JSI.

cpp
// CalculatorHostObject.cpp — implementering av JSI-omslag
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();
    }
};

I denna kod anropas metoden get varje gång JS når en egenskap hos objektet. Om egenskapens namn är „tillägg” returneras en C++-funktion som tar emot två argument från JS och anropar calc.add(). Värdet returneras som jsi::Value — JSI konverterar automatiskt double till ett JS-tal.

Anrop från JavaScript

Efter registrering av Host Object i JS-miljön ser anropet ut som en vanlig JS-funktion. Alla typer kontrolleras i kodgenereringsfasen, vilket eliminerar typmatchningsfel under exekveringen.

js
// JavaScript — anropa C++-kalkylator via JSI
import { Calculator } from 'react-native-calculator'

const result = Calculator.add(5, 3)
console.log(result) // 8 — synkront, ingen fördröjning

const product = Calculator.multiply(4, 2.5)
console.log(product) // 10 — omedelbart resultat

Observera: resultatet returneras omedelbart, utan Promise, utan await, utan callbacks. Detta är ett synkront anrop, som var omöjligt i Bridge-arkitekturen. För långvariga operationer (filläsning, nätverksbegäran) bör asynkrona mönster användas — JSI eliminerar inte behovet av bakgrundstrådar för tunga uppgifter.

I praktiken skriver de flesta utvecklare inte JSI Host Objects manuellt — detta arbete utförs av Codegen, som genererar C++-omslag baserat på TypeScript-specifikationer. Men förståelse för hur JSI fungerar under huven är nödvändig för effektiv prestandafelsökning och vid skapande av komplexa nativa moduler som kräver direkt åtkomst till C++-bibliotek (Skia, FFmpeg, OpenCV).

Vanliga frågor

Vad är skillnaden mellan JSI och Bridge i React Native?

Bridge fungerar asynkront via JSON-serialisering och en meddelandekö — varje anrop kräver 3–10 ms för datakonvertering. JSI ger synkron direkt åtkomst till C++-objekt utan serialisering, vilket minskar fördröjningen till 0.1–0.5 ms. JSI stöder också överföring av referenser till objekt, inte deras kopior.

Stöder JSI alla JavaScript-motorer?

Ja, JSI tillhandahåller ett enhetligt C++-API som är implementerat för Hermes (standard i React Native), JavaScriptCore (iOS) och V8 (Android). Utvecklaren behöver inte skriva olika kod för olika motorer — Fabric och TurboModules fungerar på samma sätt på alla motorer som stöds.

Kan gamla nativa moduler användas med JSI?

Ja, React Native tillhandahåller ett bakåtkompatibilitetslager. Native moduler skrivna för Bridge fortsätter att fungera i den nya arkitekturen. Det rekommenderas dock att migrera dem till TurboModules för att dra nytta av JSI:s fördelar — lat laddning och synkrona anrop.

Kräver JSI C++-kunskaper?

För daglig utveckling — nej. TypeScript-specifikationerna för nativa moduler kompileras automatiskt till C++-omslag via Codegen. C++-kunskaper behövs endast när man skapar egna C++-bibliotek eller vid felsökning av JSI prestanda på runtime-nivå.

Vilka problem löser JSI?

JSI löser tre viktiga problem med Bridge: hög fördröjning på grund av JSON-serialisering, brist på synkrona anrop och oförmåga att överföra komplexa objekt via referens. JSI möjliggör också direkt integration av C++-bibliotek utan Java- eller Objective-C-lager.

Sammanfattning

  • JSI (JavaScript Interface) — teknik för direkt synkron åtkomst från JavaScript till C++-objekt i React Native
  • Arkitektur JSI bygger på Host Objects — C++-objekt som exporteras till JS som nativa JS-objekt
  • Prestanda anrop via JSI är 10–50 gånger högre än via Bridge tack vare avsaknaden av serialisering
  • Fabric och TurboModules — nyckelkomponenter i den nya React Native-arkitekturen byggda på JSI
  • Synkronicitet JSI förenklar kodlogiken men kräver försiktighet vid långa operationer
  • C++-integration möjliggör anslutning av alla nativa bibliotek utan plattformsspecifika omslag
  • Använd JSI för högpresterande nativa moduler och migrera befintliga från Bridge

Vi utvecklar en mobil applikation nyckelfärdigt

IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.

Diskutera projektet

Läs också