Turbo Module คือวิวัฒนาการของโมดูลเนทีฟ React Native ที่สร้างบน JavaScript Interface (JSI) ซึ่งแตกต่างจาก Bridge ตรงที่ Turbo Module ทำงานแบบซิงโครนัสและไม่ต้องใช้การซีเรียลไลซ์ JSON จึงมอบประสิทธิภาพที่เพิ่มขึ้นอย่างมาก ตามMeta Engineering Blog, 2024 Turbo Module เป็นส่วนประกอบสำคัญของสถาปัตยกรรมใหม่และพร้อมใช้งานใน React Native 0.76+
ประเด็นสำคัญ
Turbo Module คือส่วนประกอบของสถาปัตยกรรมใหม่ React Native ที่แทนที่ Bridge แบบคลาสสิกสำหรับการสื่อสารระหว่าง JavaScript และโค้ดเนทีฟ แตกต่างจาก Bridge ที่ข้อความทุกข้อความถูกซีเรียลไลซ์เป็น JSON และส่งแบบอะซิงโครนัส Turbo Module ใช้ JSI ซึ่งเป็นเลเยอร์ที่อนุญาตให้ JavaScript เรียกใช้ฟังก์ชันที่เขียนด้วย C++ ได้โดยตรง
สถาปัตยกรรม Turbo Module ถูกนำเสนอโดยทีม Meta ในงาน React Conf 2021 ซึ่งเป็นส่วนหนึ่งของการปรับโครงสร้างครั้งใหญ่ของ React Native ภายใต้รหัส «The New Architecture» นอกเหนือจาก Turbo Module แล้ว สถาปัตยกรรมใหม่ยังรวมถึง Fabric (เรนเดอเรอร์ใหม่), Codegen (เครื่องมือสร้างโค้ด) และ JSI (อินเทอร์เฟซการโต้ตอบ) ส่วนประกอบเหล่านี้ร่วมกันแก้ไขปัญหาประสิทธิภาพที่สะสมใน React Native ตั้งแต่ปี 2015
Turbo Module แก้ปัญหาสำคัญสามประการของโมดูลเนทีฟแบบคลาสสิก: ความไม่ประสานเวลา (การเรียกทั้งหมดต้องผ่านคิว), การซีเรียลไลซ์ (ทุกการเรียกต้องแปลง JSON) และการโหลด (โมดูลทั้งหมดถูกเริ่มต้นเมื่อเริ่มต้นแอป) ด้วย Turbo Module เมธอดเนทีฟจะถูกเรียกแบบ ซิงโครนัส ข้อมูลถูกถ่ายโอนโดยไม่ต้องคัดลอก และโมดูลถูกโหลดตามความต้องการ
JSI (JavaScript Interface) คือ C++ API ที่สร้างเลเยอร์ระหว่างเอนจิน JavaScript (Hermes หรือ JSC) และโค้ดเนทีฟ JSI จัดเตรียมโฮสต์ออบเจ็กต์ — ออบเจ็กต์ C++ ที่ดูเหมือนออบเจ็กต์และเมธอด JavaScript ทั่วไป เมื่อ JavaScript เรียกใช้เมธอดของออบเจ็กต์ดังกล่าว JSI จะดำเนินการโค้ด C++ ที่เกี่ยวข้องโดยตรงโดยไม่ต้องซีเรียลไลซ์และไม่ต้องสลับเธรด
ความแตกต่างหลักระหว่าง JSI และ Bridge คือ ไม่มีการคัดลอกข้อมูล ใน Bridge แต่ละค่าจะถูกซีเรียลไลซ์เป็นสตริง JSON ส่งผ่านคิวและดีซีเรียลไลซ์ JSI ส่งพอยน์เตอร์ไปยังข้อมูลในหน่วยความจำ ทำให้สามารถทำงานกับข้อมูลปริมาณมากได้โดยไม่สูญเสียประสิทธิภาพ จากการทดสอบของ Meta การเรียก JSI ทำงานเร็วกว่าการเรียกเทียบเท่าผ่าน Bridge 5–10 เท่า
JSI กำหนดอินเทอร์เฟซ HostObject — คลาส C++ ที่ React Native ลงทะเบียนในสภาพแวดล้อม JS เป็นออบเจ็กต์ทั่วไป เมื่อโค้ด JS เข้าถึงคุณสมบัติหรือเรียกใช้เมธอดของ HostObject JSI จะสกัดกั้นการเรียกและดำเนินการโค้ด C++ ซึ่งช่วยให้ดำเนินการแบบซิงโครนัสได้โดยไม่ต้องรอคิวของ Bridge
// ตัวอย่าง JSI HostObject — การเรียกเนทีฟแบบซิงโครนัส
class ImageCompressorHostObject : public jsi::HostObject {
jsi::Value get(
jsi::Runtime& rt,
const jsi::PropNameID& propName
) override {
auto name = propName.utf8(rt);
if (name == "compressImage") {
return jsi::Function::createFromHostFunction(
rt,
jsi::PropNameID::forUtf8(rt, name),
2,
[](jsi::Runtime& rt,
const jsi::Value& thisValue,
const jsi::Value* args,
size_t count) -> jsi::Value {
return jsi::Value(rt, compressNative(
args[0].asString(rt).utf8(rt),
args[1].asNumber()
));
}
);
}
return jsi::Value::undefined();
}
};
โค้ดด้านบนแสดงให้เห็นว่า JSI HostObject จัดการการเรียก compressImage จาก JavaScript อย่างไร ฟังก์ชันรับอาร์กิวเมนต์สองตัว (สตริงพาธและหมายเลขคุณภาพ) เรียกฟังก์ชันเนทีฟ compressNative และส่งคืนผลลัพธ์ — ทั้งหมดแบบซิงโครนัส ไม่ต้องใช้ Bridge ไม่ต้องใช้ JSON นี่คือข้อได้เปรียบสำคัญของ JSI เหนือสถาปัตยกรรมดั้งเดิม
JSI เป็นส่วนหนึ่งของ รันไทม์หลักของ React Native และไม่ขึ้นอยู่กับเอนจิน JavaScript เฉพาะใด ๆ มันทำงานได้ทั้งกับ Hermes และ JavaScriptCore (JSC) โดยให้อินเทอร์เฟซแบบรวมสำหรับการโต้ตอบกับสภาพแวดล้อมเนทีฟ
การเปรียบเทียบระหว่าง Turbo Module และ Bridge แสดงให้เห็นวิวัฒนาการของสถาปัตยกรรม React Native Bridge ถูกออกแบบมาสำหรับการเปิดตัว React Native อย่างรวดเร็วในปี 2015 แต่เมื่อความซับซ้อนของแอปพลิเคชันเพิ่มขึ้น ข้อจำกัดของมันก็กลายเป็นปัญหา Turbo Module แก้ไขปัญหาเหล่านี้ในระดับสถาปัตยกรรม
| คุณลักษณะ | Bridge | Turbo Module |
|---|---|---|
| ความเร็วในการเรียก | 5–15 ms โอเวอร์เฮด | 0.1–0.5 ms โอเวอร์เฮด |
| ซิงโครนัส | แบบอะซิงโครนัสเท่านั้น | ซิงโครนัสและอะซิงโครนัส |
| การซีเรียลไลซ์ | JSON ทุกการเรียก | ออบเจ็กต์ JSI ไม่ต้องคัดลอก |
| ความปลอดภัยของชนิด | ไม่มี | Codegen + TypeScript |
| การเริ่มต้น | โมดูลทั้งหมดเมื่อเริ่มต้น | แบบ Lazy ตามความต้องการ |
ในทางปฏิบัติ ความแตกต่างจะเห็นได้ชัดที่สุดเมื่อมีการเรียกเมธอดเนทีฟบ่อยครั้ง — เช่น การประมวลผลสื่อหรือการทำงานกับ GPU สำหรับการเรียกที่หายาก (ครั้งละหนึ่งครั้งต่อเซสชัน) ความแตกต่างด้านประสิทธิภาพไม่มีนัยสำคัญ Turbo Module ยังช่วยให้ทำงานกับข้อมูลไบนารีขนาดใหญ่ — รูปภาพ วิดีโอ โปรโตคอลไบนารี — ได้ง่ายขึ้น ซึ่งใน Bridge ต้องใช้วิธีแก้ปัญหาชั่วคราวกับระบบไฟล์
การสร้าง Turbo Module เริ่มต้นด้วยการกำหนดสเปก TypeScript Codegen จะสร้างอินเทอร์เฟซ C++ และสตับ Objective-C/Java โดยอัตโนมัติตามสเปกนี้ ซึ่งเปลี่ยนแปลงแนวทางการพัฒนาอย่างสิ้นเชิง — นักพัฒนาอธิบาย API เพียงครั้งเดียวและ Codegen จะสร้างทุกอย่างอื่น
// ImageCompressor.ts — สเปก Turbo Module
import type { TurboModule } from 'react-native';
import type { Double } from 'react-native/Libraries/Types/CodegenTypes';
export interface Spec extends TurboModule {
compressImage(
imagePath: string,
quality: Double
): Promise<string>;
}
Codegen วิเคราะห์สเปก TypeScript และสร้าง C++ HostObject, โปรโตคอล Objective-C และอินเทอร์เฟซ Java นักพัฒนาเพียงแค่ต้องimplement ตรรกะเนทีฟเท่านั้น แนวทางนี้รับประกันว่าชนิดข้อมูลในฝั่ง JavaScript และฝั่งเนทีฟจะตรงกันเสมอ ช่วยขจัดข้อผิดพลาดจากการแมปด้วยตนเอง
// การimplement TurboModule สำหรับ iOS (สตับที่สร้างขึ้น)
@interface ImageCompressorModule ()
RCT_EXPORT_MODULE(ImageCompressor)
@end
@implementation ImageCompressorModule
RCT_EXPORT_METHOD(compressImage:(NSString *)imagePath
quality:(NSNumber *)quality
resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
{
NSData *compressed = [ImageProcessor compressAtPath:imagePath
quality:quality.doubleValue];
resolve([NSString stringWithUTF8String:compressed.UTF8String]);
}
@end
ข้อได้เปรียบที่สำคัญคือ การโหลดแบบ Lazy Turbo Module ไม่ได้ถูกเริ่มต้นเมื่อเริ่มต้นแอป แต่จะถูกสร้างขึ้นเมื่อมีการเข้าถึงครั้งแรกจาก JavaScript เท่านั้น ซึ่งช่วยลดเวลาเริ่มต้นแอปได้ 30–50% เมื่อเทียบกับแนวทางดั้งเดิมที่โหลดโมดูลเนทีฟทั้งหมดทันที
การเปลี่ยนจาก Bridge ไปยัง Turbo Module ไม่จำเป็นต้องเขียนแอปพลิเคชันใหม่ทั้งหมด React Native 0.73+ รองรับสถาปัตยกรรมทั้งสองแบบควบคู่กัน — โมดูล Bridge ยังคงทำงานต่อไป และโมดูลใหม่สามารถสร้างเป็น Turbo Module ได้ ซึ่งช่วยให้สามารถย้ายได้ทีละโมดูลอย่างค่อยเป็นค่อยไป
เพื่อเปิดใช้งานสถาปัตยกรรมใหม่ในโปรเจกต์ React Native 0.76+ ให้ตั้งค่าแฟล็ก newArchEnabled เป็น true ในไฟล์ react-native.config.js หลังจากนั้น โมดูลเนทีฟที่มีอยู่ทั้งหมดยังคงทำงานผ่าน Bridge และโมดูลใหม่สามารถสร้างเป็น Turbo Module ได้ Codegen จัดการทั้งสองตัวเลือกโดยอัตโนมัติ
// react-native.config.js — เปิดใช้งานสถาปัตยกรรมใหม่
module.exports = {
project: {
ios: {},
android: {},
},
assets: [],
newArchEnabled: true,
};
ขอแนะนำให้เริ่มย้ายจากโมดูลที่ถูกเรียกจาก JavaScript บ่อยที่สุด — โมดูลเหล่านี้จะได้รับประสิทธิภาพเพิ่มขึ้นมากที่สุด โมดูลที่ถูกเรียกน้อยครั้ง (ครั้งละหนึ่งครั้งต่อเซสชัน) สามารถคงไว้บน Bridge ได้โดยไม่สูญเสียประสิทธิภาพอย่างมีนัยสำคัญ
คำถามที่พบบ่อย
ไม่ Turbo Module ต้องใช้ React Native 0.73+ ที่เปิดใช้งานสถาปัตยกรรมใหม่แล้ว ตั้งแต่เวอร์ชัน 0.76 เป็นต้นไป สถาปัตยกรรมใหม่มีความเสถียรและแนะนำสำหรับโปรเจกต์ที่ใช้งานจริง
ใช่ Turbo Module รองรับทั้งสองแพลตฟอร์ม JSI เป็นเลเยอร์ C++ ที่ข้ามแพลตฟอร์ม และ Codegen สร้างสตับ Objective-C และ Java สำหรับ iOS และ Android ตามลำดับ
ไม่ Turbo Module ทำงานกับเอนจิน JS ใด ๆ ผ่าน JSI อย่างไรก็ตาม Hermes เป็นที่แนะนำเนื่องจากถูกปรับให้เหมาะสมสำหรับการทำงานกับ JSI และสถาปัตยกรรม React Native ใหม่
การดีบัก Turbo Module ทำได้ผ่าน Xcode หรือ Android Studio เช่นเดียวกับโค้ดเนทีฟทั่วไป นอกจากนี้ยังมี Flipper สำหรับติดตามการเรียก JSI และประสิทธิภาพของโมดูล
Turbo Module แทบไม่มีผลต่อขนาดแอป โค้ด C++ ของ JSI เป็นส่วนหนึ่งของ React Native อยู่แล้ว และโค้ดที่สร้างขึ้นมีขนาดเล็กมาก — เฉพาะอินเทอร์เฟซโดยไม่มีการซ้ำซ้อนของตรรกะ
สรุป
เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร
IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ