JSI (JavaScript Interface), React Native'de JavaScript'ten C++ nesnelerine ve işlevlerine doğrudan senkron erişim sağlayan ve asenkron JSON köprüsü Bridge'in yerini alan bir yazılım katmanıdır. Selefinden farklı olarak JSI, mesaj serileştirmesi olmadan yerel yöntemleri çağırmaya ve C++ nesnelerine referansları doğrudan JS ortamına aktarmaya olanak tanır. React Native Ekibi (2025)'ne göre, JSI, veri yoğun senaryolarda JS-yerel kod etkileşiminde 10 kata kadar hızlanma sağlar.
Önemli Noktalar
JSI (JavaScript Interface), JavaScript motoruna (Hermes, JavaScriptCore, V8) C++ nesnelerine, işlevlerine ve belleğine doğrudan erişim yeteneği sağlayan bir C++ katmanıdır. Çağrıları JSON'a serileştiren ve asenkron bir kuyruktan geçiren Bridge'in aksine JSI, JS kodunun senkron olarak C++ yöntemlerini çağırmasına ve sonucu hemen almasına olanak tanır.
JSI, React Native 0.64'te Yeni Mimari'nin bir parçası olarak tanıtıldı. Ana hedef, Bridge'in temsil ettiği darboğazı ortadan kaldırmaktı: JS ve yerel kod arasındaki her etkileşim, serileştirme, serileştirme çözme ve mesaj kuyruğundan geçme süresi harcıyordu. JSI, jsi::Value, jsi::Object ve jsi::Function arayüzlerini uygulayan sarmalayıcılar aracılığıyla JS motoruna C++ nesnelerine doğrudan erişim vererek bu sorunu çözer.
JSI, Bridge'in bire bir yerine geçen bir şey değildir — entegrasyona temelde farklı bir yaklaşımdır. Bridge bir posta kutusu gibi çalışıyordu: JS bir mesaj gönderir, kuyruktan geçer, yerel taraf işler ve bir yanıt gönderirdi. JSI bir işaretçi gibi çalışır: JS, bir C++ nesnesine referans alır ve normal JS işlevleri gibi yöntemlerini senkron olarak çağırabilir. Bu, iki ortam arasındaki etkileşim mimarisinde temel bir farktır.
JSI ihtiyacı, React Native 2015'te oluşturulan orijinal Bridge'in sınırlamalarından doğdu. Çerçevenin popülerliği arttıkça ve uygulamalar karmaşıklaştıkça, performans sorunu belirgin hale geldi: her yerel modül çağrısı, serileştirme için en az 3–5 ms gerektiriyordu. Bir sensör değerini okumak veya ekran boyutunu almak gibi basit işlemler için bu kabul edilebilirdi, ancak animasyonlar, grafik çalışmaları ve akış veri işleme için kritikti. React Native ekibi, 2019'da yeni mimari üzerinde çalışmaya başladı ve JSI onun temeli oldu.
JSI, JavaScript motorlarının üzerinde bir soyutlama katmanı olarak tasarlanmıştır. Her bir motor için uygulanan birleşik bir C++ API sağlar: Hermes, JavaScriptCore (iOS), V8 (Android). Bu, geliştiricilerin motorlar arasındaki farklılıklar hakkında endişelenmelerine gerek olmadığı anlamına gelir — Fabric ve TurboModules, hangi JS motorunun kullanıldığına bakılmaksızın aynı şekilde çalışır.
JSI'nin özünde Ana Bilgisayar Nesneleri (Host Objects) kavramı yatar — C++ nesneleri, yerel JS nesneleri olarak JS ortamına aktarılır. JS kodu böyle bir nesnenin bir özelliğine veya yöntemine eriştiğinde, JSI çağrıyı keser ve ilgili C++ yöntemine devreder. Bu, senkron olarak, aynı iş parçacığında, bağlam değiştirme olmadan ve bir JSON dizesi için bellek ayırmadan gerçekleşir.
Her ana bilgisayar nesnesi, get, set ve getPropertyNames yöntemleriyle jsi::HostObject arayüzünü uygular. JS motoru, nesnenin bir özelliğine her erişildiğinde bu yöntemleri çağırır. Örneğin, JS'de NativeModule.someMethod() çağrılırken JSI, bu çağrıyı ilgili ana bilgisayar nesnesi yönteminin bir C++ çağrısına dönüştürür. Dönüş değeri, jsi::Value olarak JS'ye geri gönderilir — bir sayıyı, dizeyi, boole değerini, nesneyi veya undefined'ı temsil edebilen genel bir tür.
JSI'nin önemli bir özelliği, mesaj kuyruğunun olmamasıdır. Bridge asenkron bir kuyruk kullanıyordu: JS bir istek gönderir, diğer görevlere geçer, yerel taraf isteği işler ve sonuç bir geri çağırma (callback) aracılığıyla döndürülürdü. JSI senkron çalışır: JS, JSI aracılığıyla bir yerel modül yöntemini çağırırsa, sonuç alınana kadar JS kodu yürütmesi duraklatılır. Bu, mantığı basitleştirir (geri çağırmaları beklemeye gerek yoktur) ve yarış koşullarını ortadan kaldırır, ancak dikkat gerektirir — uzun senkron çağrılar JS iş parçacığını bloke eder.
JSI aracılığıyla oluşturulan değerler, JS motoru çalışma zamanında yaşar ve çöp toplayıcı tarafından yönetilir. C++ kodu bir jsi::String veya jsi::Object oluşturup JS'ye döndürdüğünde, ortam belleği otomatik olarak yönetir. C++ kodu, çağrılar arasında bir JS değerine referans tutmak isterse, jsi::Value::getWeak() veya çalışma zamanı kök nesnesinde depolanan bir referansla genel jsi::Object::setProperty kullanılır. Bu, çöp toplayıcı tarafından erken silinmeyi önler.
JSI varsayılan olarak iş parçacığı güvenli değildir. Tüm JSI yöntem çağrıları, JS'nin yürütüldüğü iş parçacığından (genellikle React Native'in JS iş parçacığı) gerçekleşmelidir. Bir yerel modül ayrı bir iş parçacığında arka plan çalışması başlatırsa, sonuç TurboModules'tan runOnJS kullanılarak JS iş parçacığı aracılığıyla geri gönderilmelidir. Bu sınırlama, senkronizasyonun ve serileştirme yokluğunun bedelidir.
JSI ve Bridge arasındaki fark temeldir ve JS-yerel kod etkileşiminin tüm yönlerini etkiler. Bridge asenkrondu, verileri JSON'a serileştirir ve bir mesaj kuyruğu kullanırdı; JSI senkron, yerel referanslarla çalışır ve serileştirme gerektirmez.
| Parametre | Bridge | JSI |
|---|---|---|
| Çağrı Modeli | Asenkron kuyruk | Senkron doğrudan çağrı |
| Serileştirme | JSON (serileştirme + serileştirme çözme) | Yok (C++ nesnelerine doğrudan referanslar) |
| Gecikme | Çağrı başına 3–10 ms | Çağrı başına 0.1–0.5 ms |
| Tiplerne | Dinamik (JSON ile) | Statik (Codegen ile) |
| C++ Entegrasyonu | Sadece yerel modüllerle (Java/ObjC) | Doğrudan, aracısız |
| İş Parçacığı | Ayrı yerel iş parçacığı | JS iş parçacığı (senkron) |
React Native Ekibi'ne göre, Facebook Marketplace uygulamasında Bridge'den JSI'ye geçiş, JS ve yerel taraflar arasındaki veri tekrarını ortadan kaldırarak başlatma süresini %35 azalttı ve bellek tüketimini %20 düşürdü.
Bridge bir “hata” değildi — 2015'te React Native'in oluşturulması sırasında haklı bir mimari karardı. Farklı dillere sahip iki platform için yerel geliştirme, evrensel bir değişim biçimi gerektiriyordu. Bir serileştirme biçimi olarak JSON, tüm platformlarda mevcuttu ve etkileşimi birleştirmeye izin veriyordu. Sorun daha sonra, React Native saniyede binlerce yerel modül çağrısı olan karmaşık uygulamalar için kullanılmaya başlandığında belirgin hale geldi.
React Native geriye dönük uyumluluğu korur: Bridge için yazılmış yerel modüller, uyumluluk katmanı aracılığıyla yeni mimaride çalışmaya devam eder. Ancak, yeni modüller için doğrudan TurboModules aracılığıyla JSI kullanılması önerilir. Mevcut modüllerin taşınması, modülün iş mantığını değiştirmeden etkileşim protokolünün değiştirilmesini içerir.
JSI, yeni React Native mimarisinin tüm bileşenlerinin üzerine inşa edildiği temel bir katmandır. JSI olmadan ne Fabric (yeni oluşturucu) ne de TurboModules (optimize edilmiş yerel modüller) mümkün olmazdı. JSI, JS'nin tüm seviyelerde C++ ile etkileşime girmesi için birleşik bir yol sağlar.
Fabric, C++ UI temsillerine senkron erişim için JSI kullanan yeni React Native oluşturucusudur. Eski mimaride, oluşturma Bridge üzerinden gerçekleşiyordu: JS, React öğeleri oluşturur, bunları JSON'a serileştirir, Bridge üzerinden gönderir, yerel taraf serileştirmeyi çözer ve arayüzü oluştururdu. Fabric, JSI aracılığıyla doğrudan JS'den C++ Shadow Tree nesneleri oluşturur, Yoga aracılığıyla senkron olarak Düzeni hesaplar ve hazır çerçeveleri yerel oluşturucuya iletir — tek bir serileştirme olmadan.
TurboModules, React Native yerel modüllerinin evrimidir. Bir modülü Bridge'e kaydetmek ve yöntemlerini JSON üzerinden çağırmak yerine, TurboModules, yavaş yükleme ve doğrudan çağırma için JSI kullanır. JS kodu bir modüle ilk kez eriştiğinde, JSI bir ana bilgisayar nesnesi oluşturur — yerel modülü yükler ve yöntemlerini C++ işlevleri olarak sunar. Yavaş yükleme, modülün ilk erişime kadar bellek tüketmediği anlamına gelir — bu, çoğu yalnızca belirli ekranlarda kullanılan düzinelerce yerel modüle sahip uygulamalar için özellikle önemlidir.
Yeni mimaride JSI ile çalışmak için Codegen kullanılır — JavaScript özelliklerinden C++ bağlamaları oluşturan bir araç. Geliştirici, TypeScript veya Flow'da yerel modül arayüzünü tanımlar ve Codegen, JSI uyumlu bir ana bilgisayar nesnesi uygulayan C++ kodu oluşturur. Bu, rutin çalışmayı otomatikleştirir ve JS ve C++ taraflarındaki türlerin senkronize olmasını garanti eder.
Pratikte JSI ile çalışmanın nasıl göründüğüne bakalım. Bu örnekte, JSI aracılığıyla JS'ye aktarılan basit bir C++ sınıfı oluşturuyor ve React Native'deki JavaScript kodundan yöntemini çağırıyoruz.
// Calculator.h — JS'den erişilebilir C++ sınıfı başlığı
class Calculator {
public:
double add(double a, double b) { return a + b; }
double multiply(double a, double b) { return a * b; }
};
Calculator sınıfı iki aritmetik yöntem içerir. JS'den erişilebilir hale getirmemiz gerekiyor. Bunun için, Calculator'ı saran ve yöntemlerini JSI aracılığıyla sunan bir ana bilgisayar nesnesi oluşturulur.
// CalculatorHostObject.cpp — JSI sarmalayıcı uygulaması
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();
}
};
Bu kodda, get yöntemi, JS nesnenin bir özelliğine her eriştiğinde çağrılır. Özellik adı “add” ise, JS'den iki argüman alan ve calc.add()'ı çağıran bir C++ işlevi döndürülür. Değer, jsi::Value olarak döndürülür — JSI otomatik olarak double'ı JS sayısına dönüştürür.
Ana bilgisayar nesnesini JS ortamına kaydettikten sonra, çağrı normal bir JS işlevi gibi görünür. Tüm türler, kod oluşturma aşamasında kontrol edilir ve çalışma zamanı sırasında tür uyuşmazlığı hatalarını ortadan kaldırır.
// JavaScript — JSI aracılığıyla C++ hesap makinesini çağırma
import { Calculator } from 'react-native-calculator'
const result = Calculator.add(5, 3)
console.log(result) // 8 — senkron, gecikmesiz
const product = Calculator.multiply(4, 2.5)
console.log(product) // 10 — anında sonuç
Not: sonuç hemen döndürülür, Promise, await veya geri çağırmalar olmadan. Bu, Bridge mimarisinde imkansız olan bir senkron çağrıdır. Uzun süreli işlemler (dosya okuma, ağ isteği) için asenkron desenler kullanılmalıdır — JSI, ağır görevler için arka plan iş parçacıkları ihtiyacını ortadan kaldırmaz.
Uygulamada, çoğu geliştirici JSI ana bilgisayar nesnelerini manuel olarak yazmaz — bu iş, TypeScript özelliklerine dayalı C++ sarmalayıcıları oluşturan Codegen tarafından yapılır. Ancak, JSI'nin perde arkasında nasıl çalıştığını anlamak, etkili performans hata ayıklaması ve C++ kitaplıklarına (Skia, FFmpeg, OpenCV) doğrudan erişim gerektiren karmaşık yerel modüller oluştururken gereklidir.
Sıkça Sorulan Sorular
Bridge, JSON serileştirme ve mesaj kuyruğu aracılığıyla asenkron çalışır — her çağrı veri dönüşümü için 3–10 ms alır. JSI, serileştirme olmadan C++ nesnelerine senkron doğrudan erişim sağlayarak gecikmeyi 0.1–0.5 ms'ye düşürür. JSI ayrıca kopyalar yerine nesne referanslarının iletilmesini de destekler.
Evet, JSI, Hermes (React Native varsayılanı), JavaScriptCore (iOS) ve V8 (Android) için uygulanmış birleşik bir C++ API sağlar. Geliştiricilerin farklı motorlar için farklı kod yazması gerekmez — Fabric ve TurboModules, desteklenen tüm motorlarda aynı şekilde çalışır.
Evet, React Native geriye dönük uyumluluk katmanı sağlar. Bridge için yazılmış yerel modüller, yeni mimaride çalışmaya devam eder. Ancak, JSI'nin avantajlarından — yavaş yükleme ve senkron çağrılar — yararlanmak için bunların TurboModules'a taşınması önerilir.
Günlük geliştirme için — hayır. Yerel modüllerin TypeScript özellikleri, Codegen aracılığıyla otomatik olarak C++ bağlamalarına derlenir. C++ bilgisi yalnızca özel C++ kitaplıkları oluştururken veya çalışma zamanı seviyesinde JSI performansında hata ayıklarken gereklidir.
JSI, Bridge'in üç temel sorununu çözer: JSON serileştirme nedeniyle yüksek gecikme, senkron çağrıların olmaması ve karmaşık nesnelerin referansla iletilememesi. JSI ayrıca Java veya Objective-C aracıları olmadan C++ kitaplıklarını doğrudan entegre etmeye olanak tanır.
Özet
Anahtar teslim bir mobil uygulama geliştireceğiz
IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.
Ayrıca okuyun