JSI: คืออะไร หลักการทำงานและสถาปัตยกรรม

ผู้แต่ง: IT Sectr เผยแพร่เมื่อ: 2026-06-04 เวลาอ่าน: 10 นาที

JSI (JavaScript Interface) คือชั้นซอฟต์แวร์ใน React Native ที่ให้การเข้าถึงแบบซิงโครนัสโดยตรงจาก JavaScript ไปยังอ็อบเจกต์และฟังก์ชันของ C++ แทนที่ Bridge ซึ่งเป็นสะพาน JSON แบบอะซิงโครนัส ต่างจากรุ่นก่อนหน้า 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 มิลลิวินาทีในการซีเรียไลซ์ สำหรับการดำเนินการง่ายๆ เช่นการอ่านค่าจากเซนเซอร์หรือการรับขนาดหน้าจอ นี่ถือว่ารับได้ แต่สำหรับแอนิเมชัน การทำงานกับกราฟิก และการประมวลผลข้อมูลแบบสตรีม — ถือว่าวิกฤต ทีม React Native เริ่มทำงานกับสถาปัตยกรรมใหม่ในปี 2019 และ JSI กลายเป็นรากฐานของมัน

การรองรับเอนจิน JavaScript

JSI ถูกออกแบบให้เป็นชั้นนามธรรมเหนือเอนจิน JavaScript โดยมี API C++ เดียวที่ถูกนำไปใช้กับเอนจินเฉพาะแต่ละตัว: 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 จะหยุดชั่วคราวจนกว่าจะได้รับผลลัพธ์ ซึ่งทำให้ตรรกะง่ายขึ้น (ไม่ต้องรอ callbacks) และขจัดrace conditions แต่ต้องระมัดระวัง — การเรียกแบบซิงโครนัสที่ใช้เวลานานจะบล็อกเธรด JS

วงจรชีวิตของค่า JSI

ค่าที่สร้างผ่าน JSI อาศัยอยู่ใน runtime ของเอนจิน JS และถูกจัดการโดยตัวเก็บขยะ (garbage collector) เมื่อโค้ด 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 เทียบกับ Bridge: การเปรียบเทียบ

ความแตกต่างระหว่าง JSI และ Bridge มีลักษณะเป็นพื้นฐานและส่งผลต่อทุกด้านของการโต้ตอบระหว่าง JS และโค้ดเนทีฟ Bridge เป็นแบบอะซิงโครนัส ซีเรียไลซ์ข้อมูลเป็น JSON และใช้คิวข้อความ ส่วน JSI เป็นแบบซิงโครนัส ทำงานกับการอ้างอิงเนทีฟ และไม่ต้องซีเรียไลซ์

พารามิเตอร์BridgeJSI
รูปแบบการเรียกคิวแบบอะซิงโครนัสการเรียกตรงแบบซิงโครนัส
การซีเรียไลซ์JSON (ซีเรียไลซ์ + ดีซีเรียไลซ์)ไม่มี (การอ้างอิงตรงไปยังอ็อบเจกต์ C++)
ความหน่วง3–10 มิลลิวินาทีต่อการเรียก0.1–0.5 มิลลิวินาทีต่อการเรียก
การกำหนดชนิดข้อมูลแบบไดนามิก (ผ่าน 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 สำหรับการเข้าถึงมุมมอง UI ของ C++ แบบซิงโครนัส ในสถาปัตยกรรมเก่าการเรนเดอร์ผ่าน Bridge: JS สร้าง React elements ซีเรียไลซ์เป็น 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 ไม่มี callbacks นี่คือการเรียกแบบซิงโครนัส ซึ่งเป็นไปไม่ได้ในสถาปัตยกรรม Bridge สำหรับการทำงานที่ใช้เวลานาน (การอ่านไฟล์ การร้องขอเครือข่าย) ควรใช้รูปแบบอะซิงโครนัสของ Java — JSI ไม่ได้ยกเลิกความจำเป็นของเธรดพื้นหลังสำหรับงานหนัก

ในทางปฏิบัติ นักพัฒนาส่วนใหญ่ไม่ได้เขียน JSI Host Objects ด้วยตนเอง — งานนี้ทำโดย Codegen ซึ่งสร้างตัวห่อหุ้ม C++ ตามสเปค TypeScript อย่างไรก็ตาม การเข้าใจว่า JSI ทำงานภายใต้ฝาครอบอย่างไรนั้นจำเป็นสำหรับการดีบักประสิทธิภาพอย่างมีประสิทธิภาพและการสร้างโมดูลเนทีฟที่ซับซ้อนซึ่งต้องการการเข้าถึงไลบรารี C++ โดยตรง (Skia, FFmpeg, OpenCV)

คำถามที่พบบ่อย

JSI แตกต่างจาก Bridge ใน React Native อย่างไร?

Bridge ทำงานแบบอะซิงโครนัสผ่านการซีเรียไลซ์ JSON และคิวข้อความ — ทุกการเรียกต้องใช้ 3–10 มิลลิวินาทีในการแปลงข้อมูล JSI ให้การเข้าถึงตรงแบบซิงโครนัสไปยังอ็อบเจกต์ C++ โดยไม่ซีเรียไลซ์ ลดความหน่วงลงเหลือ 0.1–0.5 มิลลิวินาที JSI ยังรองรับการส่งการอ้างอิงไปยังอ็อบเจกต์แทนที่จะส่งสำเนา

JSI รองรับเอนจิน JavaScript ทั้งหมดหรือไม่?

ใช่ JSI ให้ API C++ เดียวที่ถูกนำไปใช้กับ 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 สูงกว่า Bridge 10–50 เท่า จากการไม่ซีเรียไลซ์
  • Fabric และ TurboModules — คอมโพเนนต์สำคัญของสถาปัตยกรรมใหม่ของ React Native ที่สร้างบน JSI
  • การซิงโครนัส ของ JSI ทำให้ตรรกะโค้ดง่ายขึ้น แต่ต้องระมัดระวังกับการทำงานที่ใช้เวลานาน
  • การบูรณาการ C++ อนุญาตให้เชื่อมต่อไลบรารีเนทีฟใดๆ โดยไม่ต้องใช้ตัวห่อหุ้มแพลตฟอร์ม
  • ใช้ JSI สำหรับโมดูลเนทีฟที่มีประสิทธิภาพสูงและย้ายโมดูลที่มีอยู่จาก Bridge

เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร

IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ

ปรึกษาโครงการ

อ่านเพิ่มเติม