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. Όσο αυξανόταν η δημοτικότητα του framework και γίνονταν πιο πολύπλοκες οι εφαρμογές, το πρόβλημα των επιδόσεων έγινε εμφανές: κάθε κλήση ενός εγγενούς module απαιτούσε τουλάχιστον 3–5 ms για σειριοποίηση. Για απλές λειτουργίες, όπως η ανάγνωση της τιμής ενός αισθητήρα ή η λήψη του μεγέθους της οθόνης, αυτό ήταν αποδεκτό, αλλά για animations, επεξεργασία γραφικών και ροή δεδομένων — κρίσιμο. Η ομάδα του 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 — ένας γενικευμένος τύπος που μπορεί να αναπαραστήσει έναν αριθμό, μια συμβολοσειρά, μια τιμή boolean, ένα αντικείμενο ή undefined.

Ένα σημαντικό χαρακτηριστικό του JSI είναι η απουσία ουράς μηνυμάτων. Το Bridge χρησιμοποιούσε ασύγχρονη ουρά: η JS έστελνε το αίτημα, προχωρούσε σε άλλες εργασίες, η εγγενής πλευρά επεξεργαζόταν το αίτημα και το αποτέλεσμα επέστρεφε μέσω callback. Το JSI λειτουργεί σύγχρονα: αν η JS καλεί μια μέθοδο ενός εγγενούς module μέσω JSI, η εκτέλεση του κώδικα JS διακόπτεται έως ότου ληφθεί το αποτέλεσμα. Αυτό απλοποιεί τη λογική (δεν χρειάζεται να περιμένει κανείς callbacks) και εξαλείφει τις race conditions, αλλά απαιτεί προσοχή — οι μεγάλες σύγχρονες κλήσεις μπλοκάρουν το νήμα JS.

Κύκλος ζωής των τιμών JSI

Οι τιμές που δημιουργούνται μέσω JSI ζουν στο runtime της μηχανής JS και διαχειρίζονται από τον συλλέκτη απορριμμάτων. Όταν ο κώδικας C++ δημιουργεί ένα jsi::String ή jsi::Object και το επιστρέφει στην JS, το περιβάλλον διαχειρίζεται αυτόματα τη μνήμη. Αν ο κώδικας C++ θέλει να διατηρήσει μια αναφορά σε τιμή JS μεταξύ κλήσεων, χρησιμοποιείται το jsi::Value::getWeak() ή το παγκόσμιο jsi::Object::setProperty με αποθήκευση της αναφοράς στο ριζικό αντικείμενο του runtime. Αυτό αποτρέπει την πρόωρη διαγραφή από τον συλλέκτη απορριμμάτων.

Ασφάλεια νημάτων

Το JSI δεν είναι ασφαλές για νήματα από προεπιλογή. Όλες οι κλήσεις μεθόδων JSI πρέπει να γίνονται από το νήμα στο οποίο εκτελείται η JS (συνήθως το νήμα JS του React Native). Αν ένα εγγενές module εκτελεί εργασία φόντου σε ξεχωριστό νήμα, το αποτέλεσμα πρέπει να μεταφέρεται πίσω μέσω του νήματος JS με την κλήση runOnJS από τα TurboModules. Αυτός ο περιορισμός είναι το τίμημα για τη συγχρονικότητα και την απουσία σειριοποίησης.

JSI vs Bridge: σύγκριση

Η διαφορά μεταξύ JSI και Bridge είναι θεμελιώδης και επηρεάζει όλες τις πτυχές της αλληλεπίδρασης της JS με τον εγγενή κώδικα. Το Bridge ήταν ασύγχρονο, σειριοποιούσε τα δεδομένα σε JSON και χρησιμοποιούσε ουρά μηνυμάτων· το JSI είναι σύγχρονο, λειτουργεί με εγγενείς αναφορές και δεν απαιτεί σειριοποίηση.

Παράμετρος Bridge JSI
Μοντέλο κλήσης Ασύγχρονη ουρά Σύγχρονη άμεση κλήση
Σειριοποίηση JSON (σειριοποίηση + αποσειριοποίηση) Όχι (άμεσες αναφορές σε αντικείμενα C++)
Καθυστέρηση 3–10 ms ανά κλήση 0.1–0.5 ms ανά κλήση
Τυποποίηση Δυναμική (μέσω JSON) Στατική (μέσω Codegen)
Ενσωμάτωση C++ Μόνο μέσω εγγενών modules (Java/ObjC) Άμεση, χωρίς ενδιάμεσους
Νήμα Ξεχωριστό εγγενές νήμα Νήμα JS (σύγχρονα)

Σύμφωνα με την React Native Team, η μετάβαση από το Bridge στο JSI στην εφαρμογή Facebook Marketplace μείωσε τον χρόνο εκκίνησης κατά 35% και τη χρήση μνήμης κατά 20% χάρη στην εξάλειψη του διπλασιασμού δεδομένων μεταξύ της πλευράς JS και της εγγενούς πλευράς.

Πότε το Bridge ήταν απαραίτητο

Το Bridge δεν ήταν «λάθος» — ήταν μια αρχιτεκτονική απόφαση, δικαιολογημένη τη στιγμή της δημιουργίας του React Native το 2015. Η εγγενής ανάπτυξη για δύο πλατφόρμες με διαφορετικές γλώσσες απαιτούσε ένα καθολικό μορφότυπο ανταλλαγής. Το JSON ως μορφότυπο σειριοποίησης ήταν διαθέσιμο σε όλες τις πλατφόρμες και επέτρεπε την ενοποίηση της αλληλεπίδρασης. Το πρόβλημα εμφανίστηκε αργότερα, όταν το React Native άρχισε να χρησιμοποιείται για πολύπλοκες εφαρμογές με χιλιάδες κλήσεις εγγενών modules ανά δευτερόλεπτο.

Αντίστροφη συμβατότητα

Το React Native διατηρεί την αντίστροφη συμβατότητα: τα εγγενή modules που γράφτηκαν για το Bridge συνεχίζουν να λειτουργούν στη νέα αρχιτεκτονική μέσω ενός επιπέδου συμβατότητας. Ωστόσο, για νέα modules συνιστάται να χρησιμοποιείτε αμέσως το JSI μέσω των TurboModules. Η μετάβαση υφιστάμενων modules είναι η αντικατάσταση του πρωτοκόλλου αλληλεπίδρασης χωρίς αλλαγή της επιχειρηματικής λογικής του ίδιου του module.

Το JSI στην αρχιτεκτονική του React Native

Το JSI είναι το θεμελιώδες επίπεδο πάνω στο οποίο χτίστηκαν όλα τα στοιχεία της νέας αρχιτεκτονικής του React Native. Χωρίς JSI είναι αδύνατη η λειτουργία τόσο του Fabric (ο νέος renderer) όσο και των TurboModules (βελτιστοποιημένα εγγενή modules). Το JSI παρέχει έναν ενιαίο τρόπο αλληλεπίδρασης της JS με τη C++ σε όλα τα επίπεδα.

Fabric και JSI

Το Fabric είναι ο νέος renderer του React Native που χρησιμοποιεί το JSI για σύγχρονη πρόσβαση στις απεικονίσεις UI της C++. Στην παλιά αρχιτεκτονική, η απόδοση γινόταν μέσω Bridge: η JS δημιουργούσε στοιχεία React, τα σειριοποιούσε σε JSON, τα έστελνε μέσω Bridge, η εγγενής πλευρά τα αποσειριοποιούσε και δημιουργούσε το UI. Το Fabric μέσω JSI δημιουργεί αντικείμενα C++ του Shadow Tree απευθείας από την JS, υπολογίζει σύγχρονα το Layout μέσω Yoga και μεταφέρει τα έτοιμα frames στον εγγενή renderer — χωρίς ούτε μία σειριοποίηση.

TurboModules και JSI

Τα TurboModules είναι η εξέλιξη των εγγενών modules του React Native. Αντί να καταχωρείται ένα module στο Bridge και να καλούνται οι μέθοδοί του μέσω JSON, τα TurboModules χρησιμοποιούν το JSI για τεμπέλη φόρτωση και άμεση κλήση. Όταν ο κώδικας JS προσπελαύνει για πρώτη φορά ένα module, το JSI δημιουργεί ένα Host Object — φορτώνει το εγγενές module και παρέχει τις μεθόδους του ως συναρτήσεις C++. Η τεμπέλη φόρτωση σημαίνει ότι το module δεν καταναλώνει μνήμη μέχρι την πρώτη προσπέλαση — αυτό είναι ιδιαίτερα σημαντικό για εφαρμογές με δεκάδες εγγενή modules, πολλά από τα οποία χρησιμοποιούνται μόνο σε συγκεκριμένες οθόνες.

Κωδογένεση μέσω JSI

Για την εργασία με το JSI στη νέα αρχιτεκτονική χρησιμοποιείται το Codegen — ένα εργαλείο που δημιουργεί περιτυλίγματα C++ από προδιαγραφές JavaScript. Ο προγραμματιστής περιγράφει τη διεπαφή του εγγενούς module σε 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, χωρίς callbacks. Αυτή είναι μια σύγχρονη κλήση που ήταν αδύνατη στην αρχιτεκτονική Bridge. Για μεγάλες λειτουργίες (ανάγνωση αρχείου, αίτημα δικτύου) θα πρέπει να χρησιμοποιούνται ασύγχρονα μοτίβα Java — το JSI δεν αναιρεί την ανάγκη για νήματα φόντου σε βαριές εργασίες.

Στην πράξη, οι περισσότεροι προγραμματιστές δεν γράφουν JSI Host Objects χειροκίνητα — αυτή την εργασία την αναλαμβάνει το Codegen, το οποίο δημιουργεί περιτυλίγματα C++ βάσει προδιαγραφών TypeScript. Ωστόσο, η κατανόηση του πώς λειτουργεί το JSI εσωτερικά είναι απαραίτητη για την αποτελεσματική αποσφαλμάτωση επιδόσεων και κατά τη δημιουργία πολύπλοκων εγγενών modules που απαιτούν άμεση πρόσβαση σε βιβλιοθήκες 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 λειτουργούν το ίδιο σε όλες τις υποστηριζόμενες μηχανές.

Μπορώ να χρησιμοποιήσω παλιά εγγενή modules με το JSI;

Ναι, το React Native παρέχει ένα επίπεδο αντίστροφης συμβατότητας. Τα εγγενή modules που γράφτηκαν για το Bridge συνεχίζουν να λειτουργούν στη νέα αρχιτεκτονική. Ωστόσο, συνιστάται η μετάβασή τους σε TurboModules για να επωφεληθείτε από τα πλεονεκτήματα του JSI — τεμπέλη φόρτωση και σύγχρονες κλήσεις.

Απαιτεί το JSI γνώσεις C++;

Για την καθημερινή ανάπτυξη — όχι. Οι προδιαγραφές TypeScript των εγγενών modules μεταγλωττίζονται σε περιτυλίγματα 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 για εγγενή modules υψηλών επιδόσεων και μεταφέρετε τα υπάρχοντα από το Bridge

Θα αναπτύξουμε μια εφαρμογή για κινητά έτοιμη για χρήση

Η IT Sectr δημιουργεί εφαρμογές iOS και Android για νεοφυείς επιχειρήσεις και επιχειρήσεις από το 2017. Θα σας συμβουλεύσουμε και θα προτείνουμε την καλύτερη λύση.

Συζήτηση έργου

Διαβάστε επίσης