Fabric — คือเรนเดอเรอร์ใหม่ของ React Native ที่เขียนใหม่ทั้งหมดด้วย C++ และรวมเข้ากับ JSI มันแทนที่การเรนเดอร์แบบเก่าที่ใช้ UIView และ ViewManager ให้การอัปเดต UI แบบซิงโครนัสและการคำนวณการเปลี่ยนแปลงอย่างมีประสิทธิภาพผ่าน Shadow Tree ตามข้อมูลจาก Meta Engineering Blog, 2024, Fabric เป็นส่วนประกอบบังคับของสถาปัตยกรรมใหม่และพร้อมใช้งานใน React Native 0.76+
สำคัญ
Fabric — คือระบบเรนเดอร์ใหม่สำหรับ React Native ที่แทนที่เรนเดอเรอร์เก่าซึ่งทำงานผ่าน Shadow Thread และ Bridge ในสถาปัตยกรรมเก่า กระบวนการเรนเดอร์มีสามขั้นตอน: JavaScript คำนวณ Virtual DOM, Shadow Thread (Yoga) คำนวณเลย์เอาต์, Native Thread วาด UIView Fabric รวมทุกขั้นตอนเหล่านี้ในไปป์ไลน์ C++ เดียวที่ทำงานแบบซิงโครนัส
การพัฒนา Fabric เริ่มขึ้นในปี 2019 โดยเป็นส่วนหนึ่งของโครงการริเริ่ม Lean Core และโครงการ “The New Architecture” เป้าหมายหลักคือการแก้ปัญหาประสิทธิภาพที่เกี่ยวข้องกับการเรนเดอร์แบบสามรอบอะซิงโครนัส ในสถาปัตยกรรมเก่า การเปลี่ยนแปลงสถานะแต่ละครั้งต้องใช้สามรอบผ่านเธรดต่างๆ ซึ่งสร้างความล่าช้าระหว่างการเปลี่ยนแปลงข้อมูลและการวาด UI
Fabric ใช้แนวคิดของ Immutable Shadow Tree แต่ละโหนดของต้นไม้แสดงถึงคอมโพเนนต์ React พร้อมด้วย props และสถานะของมัน เมื่อสถานะเปลี่ยนแปลง จะสร้างต้นไม้ใหม่ และ Fabric คำนวณความแตกต่างระหว่างต้นไม้เก่าและใหม่ และใช้เฉพาะการเปลี่ยนแปลงที่จำเป็นกับ UI ดั้งเดิม ซึ่งช่วยลดจำนวนการดำเนินการกับ UIView/ViewGroup และลดเวลาในการเรนเดอร์
Shadow Tree — คือพื้นฐานการทำงานของ Fabric แตกต่างจากสถาปัตยกรรมเก่าที่ Shadow Tree มีอยู่เฉพาะฝั่ง C++ และถูกแยกจาก JS tree ผ่าน Bridge แบบอะซิงโครนัส Fabric สร้างการแสดงลำดับชั้นของ UI ที่ซิงโครไนซ์อย่างสมบูรณ์ โหนด Shadow Tree เก็บ props สถานะ และสไตล์ของคอมโพเนนต์ ในขณะที่ Yoga คำนวณเลย์เอาต์โดยตรงที่ระดับ C++
เมื่อคอมโพเนนต์ React อัปเดตสถานะ React Native จะส่ง Shadow Node ใหม่ไปยัง Fabric Fabric ไม่ได้วาด UI ใหม่ทั้งหมด — มันใช้อัลกอริทึมการเปรียบเทียบ (diffing) ที่ระดับ C++ เพื่อระบุว่าโหนดใดเปลี่ยนแปลงไป มีเพียงโหนดที่เปลี่ยนแปลงเท่านั้นที่ถูกส่งไปยังการเรนเดอร์ดั้งเดิม ซึ่งช่วยลดปริมาณงานลงอย่างมาก
กระบวนการเรนเดอร์ใน Fabric ประกอบด้วยสามเฟสที่ทำงานแบบซิงโครนัสที่ระดับ C++ โดยไม่ต้องสลับเธรด เฟสแรก — Render: React เรียกใช้ฟังก์ชันเรนเดอร์ของคอมโพเนนต์ ซึ่งส่งคืน React Element Tree เฟสที่สอง — Commit: React Native สร้าง Shadow Tree ใหม่และคำนวณการเปลี่ยนแปลงโดยอิงจากเวอร์ชันเก่า เฟสที่สาม — Mount: Fabric ใช้การเปลี่ยนแปลงกับ UI ดั้งเดิม สร้าง อัปเดต หรือลบ UIView
ทั้งสามเฟสทำงานเป็นไปป์ไลน์เดียว โดยข้อมูลถูกส่งผ่าน JSI โดยไม่ต้อง serialize นี่คือความแตกต่างสำคัญจากสถาปัตยกรรมเก่าที่มีช่องว่างระหว่างเฟส: JS → (JSON) → Shadow Thread → (เลย์เอาต์) → Native Thread
การเปรียบเทียบ Fabric กับเรนเดอเรอร์เก่าแสดงให้เห็นว่าสถาปัตยกรรม React Native เปลี่ยนแปลงไปมากเพียงใด เรนเดอเรอร์เก่าทำงานแบบอะซิงโครนัส โดยแยกกระบวนการเรนเดอร์เป็นสามเธรดอิสระ Fabric รวมทุกอย่างเป็นไปป์ไลน์ C++ เดียว
| คุณลักษณะ | เรนเดอเรอร์เก่า | Fabric |
|---|---|---|
| สถาปัตยกรรม | สามเธรด (JS, Shadow, Native) | ไปป์ไลน์ C++ เดียว |
| ความซิงโครนัส | การเรนเดอร์แบบอะซิงโครนัส | การเรนเดอร์แบบซิงโครนัส |
| Shadow Tree | เปลี่ยนแปลงได้ มีสำเนาในแต่ละเธรด | ไม่เปลี่ยนแปลง รวมเป็นหนึ่งเดียว |
| ช่องทาง | Bridge + JSON serialization | JSI + การเรียก C++ โดยตรง |
| ประสิทธิภาพ | หน่วงเวลาสูงสุด 16 มิลลิวินาทีต่อเฟรม | หน่วงเวลาน้อยกว่า 1 มิลลิวินาทีต่อเฟรม |
ในทางปฏิบัติ Fabric มีประโยชน์โดยเฉพาะสำหรับแอปพลิเคชันที่มีการอัปเดต UI บ่อยครั้ง: แอนิเมชัน การเลื่อนที่มีส่วนหัวลอย ข้อมูล real-time สำหรับหน้าแบบคงที่ (ข้อความ ปุ่ม) ความแตกต่างจะสังเกตเห็นได้น้อยกว่า ตามข้อมูลของเกณฑ์วัด Meta Fabric ลดเวลาในการเรนเดอร์เริ่มต้นของรายการลง 40–60%
JSI (JavaScript Interface) — คือคอมโพเนนต์สำคัญที่ทำให้ Fabric เป็นไปได้ ผ่าน JSI Fabric สามารถเข้าถึงค่า JavaScript โดยตรงโดยไม่ต้อง serialize เมื่อ React ส่ง props ไปยัง Fabric พวกมันจะไม่ถูกคัดลอกผ่าน JSON — JSI ส่งพอยน์เตอร์ไปยังข้อมูลในหน่วยความจำของ JS engine
สถาปัตยกรรม JSI ทำให้ Fabric สามารถทำงานกับ JS engine ใดก็ได้ — Hermes, JSC หรือ V8 โค้ด C++ ของ Fabric ไม่ขึ้นอยู่กับการใช้งานเฉพาะของ JS engine ซึ่งทำให้การบำรุงรักษาและการทดสอบง่ายขึ้น การดำเนินการทั้งหมดกับ UI — การสร้าง การอัปเดต การลบ — ดำเนินการผ่าน JSI ซึ่งรับประกันความหน่วงเวลาน้อยที่สุด
// ไปป์ไลน์การเรนเดอร์ C++ ของ Fabric ผ่าน JSI
void mountShadowNode(
jsi::Runtime& runtime,
const ShadowNode::Shared& shadowNode,
const ShadowNode::SharedList& children
) {
auto props = shadowNode->getProps();
auto state = shadowNode->getState();
// การถ่ายโอน prop แบบซิงโครนัสผ่าน JSI
jsiValue.asObject(runtime)
.getProperty(runtime, "style")
.asObject(runtime);
// การคำนวณเลย์เอาต์ผ่าน Yoga โดยตรง
auto layoutMetrics =
YogaLayoutableShadowNode::layout(children);
// ใช้การกลายพันธุ์กับ UI ดั้งเดิม
UIManager::synchronouslyUpdateViewOnUIThread(
shadowNode->getTag(), layoutMetrics
);
}
ข้อได้เปรียบสำคัญ — การอัปเดตแบบซิงโครนัส ในสถาปัตยกรรมเก่า UI ได้รับการอัปเดตผ่านคิวอะซิงโครนัส: React ส่งคำสั่งผ่าน Bridge, Shadow Thread ประมวลผลเลย์เอาต์, Native Thread วาดภาพ ใน Fabric ทุกขั้นตอนดำเนินการตามลำดับในรอบเดียว ซึ่งช่วยขจัด race conditions และรับประกันว่า UI สอดคล้องกับสถานะปัจจุบันของแอปพลิเคชัน
การย้ายไปใช้ Fabric ไม่จำเป็นต้องเขียนคอมโพเนนต์ React ใหม่ — คอมโพเนนต์ React Native ที่มีอยู่ทั้งหมดยังคงทำงานได้ อย่างไรก็ตาม ไลบรารีที่มีโค้ดดั้งเดิม (Native Module, คอมโพเนนต์ ViewManager แบบกำหนดเอง) อาจต้องอัปเดต Meta แนะนำให้ตรวจสอบความเข้ากันได้ของแต่ละไลบรารีก่อนเปิดใช้งานสถาปัตยกรรมใหม่
หากต้องการเปิดใช้งาน Fabric ในโปรเจกต์ React Native 0.76+ ให้ตั้งค่าแฟล็ก newArchEnabled: true ใน react-native.config.js Fabric จะเปิดใช้งานโดยอัตโนมัติพร้อมกับ Turbo Module หากเกิดปัญหา สามารถปิด Fabric และกลับไปใช้เรนเดอเรอร์เก่าได้โดยไม่ต้องเปลี่ยนโค้ดของแอปพลิเคชัน — สถาปัตยกรรมทั้งสองรองรับแบบขนาน
// package.json — ตรวจสอบไลบรารีที่เข้ากันได้กับ Fabric
"react-native": "0.76.6",
"react-native-safe-area-context": "^5.0.0",
"react-native-screens": "^4.0.0",
"react-native-reanimated": "^3.16.0",
"react-native-gesture-handler": "^2.21.0"
ในการย้ายไปใช้ สิ่งสำคัญคือต้องอัปเดตไลบรารีดั้งเดิมทั้งหมดเป็นเวอร์ชันที่เข้ากันได้กับ Fabric ไลบรารีขนาดใหญ่ เช่น react-native-reanimated และ react-native-gesture-handler รองรับสถาปัตยกรรมใหม่อยู่แล้ว สำหรับไลบรารีที่ยังไม่ได้อัปเดต Fabric มีกลไกความเข้ากันได้ — หากไลบรารีไม่รองรับ Fabric เรนเดอเรอร์จะสลับไปใช้แบบเก่าสำหรับไลบรารีนั้นโดยอัตโนมัติ
คำถามที่พบบ่อย
ใช่ ตั้งแต่ Expo SDK 52 เป็นต้นไป สถาปัตยกรรมใหม่จะเปิดใช้งานตามค่าเริ่มต้น Fabric และ Turbo Module พร้อมใช้งานใน managed workflow โดยไม่ต้องตั้งค่าเพิ่มเติม
Fabric ปรับปรุงแอนิเมชันอย่างมีนัยสำคัญด้วยการเรนเดอร์แบบซิงโครนัส แอนิเมชันบน JS thread จะไม่แข่งขันกับการประมวลผลข้อความของ Bridge อีกต่อไป ซึ่งช่วยขจัดอาการกระตุกและการลดลงของ FPS
ไม่ คอมโพเนนต์ React Native มาตรฐานทั้งหมดทำงานกับ Fabric ได้โดยไม่ต้องเปลี่ยนแปลง เฉพาะ ViewManager แบบกำหนดเองเท่านั้นที่ต้องอัปเดตเพื่อรองรับสถาปัตยกรรมใหม่
ตั้งค่า newArchEnabled: false ใน react-native.config.js และสร้างแอปพลิเคชันใหม่ โมดูลและคอมโพเนนต์ทั้งหมดจะทำงานต่อไปโดยไม่ต้องเปลี่ยนแปลง — Fabric และเรนเดอเรอร์เก่าสามารถใช้แทนกันได้อย่างสมบูรณ์
Bridgeless mode — คือโหมดการทำงานของ Fabric ที่ Bridge ถูกปิดอย่างสมบูรณ์ การสื่อสารทั้งหมดผ่าน JSI เท่านั้น ซึ่งให้ประสิทธิภาพสูงสุด พร้อมใช้งานใน React Native 0.76+
สรุป
เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร
IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ
อ่านเพิ่มเติม