Fabric là một trình kết xuất React Native mới, được viết lại hoàn toàn bằng C++ và tích hợp với JSI. Nó đã thay thế trình kết xuất cũ dựa trên UIView và ViewManager, cung cấp các cập nhật UI đồng bộ và tính toán thay đổi hiệu quả thông qua Shadow Tree. Theo Meta Engineering Blog, 2024, Fabric là một thành phần bắt buộc của kiến trúc mới và có sẵn trong React Native 0.76+.
Điểm chính
Fabric là một hệ thống kết xuất mới cho React Native đã thay thế trình kết xuất cũ hoạt động thông qua Shadow Thread và Bridge. Trong kiến trúc cũ, quá trình kết xuất bao gồm ba bước: JavaScript tính toán Virtual DOM, Shadow Thread (Yoga) tính toán bố cục, Native Thread vẽ UIView. Fabric kết hợp tất cả các bước này thành một đường ống C++ duy nhất hoạt động đồng bộ.
Việc phát triển Fabric bắt đầu vào năm 2019 như một phần của sáng kiến Lean Core và dự án “The New Architecture”. Mục tiêu chính là giải quyết các vấn đề hiệu suất liên quan đến kết xuất bất đồng bộ ba vòng. Trong kiến trúc cũ, mỗi lần thay đổi trạng thái yêu cầu ba lần truyền qua các luồng khác nhau, tạo ra độ trễ giữa thay đổi dữ liệu và kết xuất UI.
Fabric dựa trên khái niệm Cây Shadow Bất biến (Immutable Shadow Tree). Mỗi nút của cây đại diện cho một thành phần React với props và trạng thái của nó. Khi trạng thái thay đổi, một cây mới được tạo ra và Fabric tính toán sự khác biệt giữa cây cũ và cây mới và chỉ áp dụng các thay đổi cần thiết lên UI gốc. Điều này giảm thiểu số lượng thao tác UIView/ViewGroup và rút ngắn thời gian kết xuất.
Shadow Tree là nền tảng hoạt động của Fabric. Không giống như kiến trúc cũ, nơi Shadow Tree chỉ tồn tại ở phía C++ và bị tách khỏi cây JS thông qua Bridge bất đồng bộ, Fabric tạo ra một biểu diễn phân cấp được đồng bộ hóa hoàn toàn của UI. Các nút Shadow Tree lưu trữ props, trạng thái và kiểu của thành phần, trong khi Yoga tính toán bố cục trực tiếp ở cấp C++.
Khi một thành phần React cập nhật trạng thái của nó, React Native gửi một Shadow Node mới đến Fabric. Fabric không kết xuất lại toàn bộ UI — nó sử dụng thuật toán so sánh (diffing) ở cấp C++ để xác định nút nào đã thay đổi. Chỉ các nút đã thay đổi mới được gửi để kết xuất gốc, giúp giảm đáng kể khối lượng công việc.
Quá trình kết xuất trong Fabric bao gồm ba giai đoạn được thực hiện đồng bộ ở cấp C++ mà không cần chuyển đổi luồng. Giai đoạn đầu tiên là Render: React gọi hàm kết xuất của thành phần, trả về một React Element Tree. Giai đoạn thứ hai là Commit: React Native tạo một Shadow Tree mới và tính toán các thay đổi dựa trên phiên bản cũ. Giai đoạn thứ ba là Mount: Fabric áp dụng các thay đổi lên UI gốc, tạo, cập nhật hoặc xóa UIViews.
Cả ba giai đoạn hoạt động như một đường ống duy nhất nơi dữ liệu được truyền qua JSI mà không cần tuần tự hóa. Đây là sự khác biệt chính so với kiến trúc cũ, nơi có khoảng cách giữa các giai đoạn: JS → (JSON) → Shadow Thread → (bố cục) → Native Thread.
So sánh Fabric với trình kết xuất cũ cho thấy kiến trúc React Native đã thay đổi đáng kể như thế nào. Trình kết xuất cũ hoạt động bất đồng bộ, chia quá trình kết xuất thành ba luồng độc lập. Fabric kết hợp mọi thứ thành một đường ống C++ duy nhất.
| Đặc điểm | Trình kết xuất cũ | Fabric |
|---|---|---|
| Kiến trúc | Ba luồng (JS, Shadow, Native) | Đường ống C++ duy nhất |
| Đồng bộ | Kết xuất bất đồng bộ | Kết xuất đồng bộ |
| Shadow Tree | Có thể thay đổi, mỗi luồng có bản sao riêng | Bất biến, thống nhất |
| Kênh | Bridge + tuần tự hóa JSON | JSI + gọi C++ trực tiếp |
| Hiệu suất | Độ trễ lên đến 16 ms mỗi khung hình | Độ trễ dưới 1 ms mỗi khung hình |
Trong thực tế, Fabric đặc biệt có lợi cho các ứng dụng có cập nhật UI thường xuyên: hoạt ảnh, cuộn với tiêu đề nổi, dữ liệu thời gian thực. Đối với các trang tĩnh (văn bản, nút) sự khác biệt ít rõ ràng hơn. Theo các benchmark của Meta, Fabric giảm thời gian kết xuất danh sách ban đầu xuống 40–60%.
JSI (JavaScript Interface) là một thành phần chính giúp Fabric khả thi. Thông qua JSI, Fabric có quyền truy cập trực tiếp vào các giá trị JavaScript mà không cần tuần tự hóa. Khi React truyền props cho Fabric, chúng không được sao chép qua JSON — JSI truyền con trỏ đến dữ liệu trong bộ nhớ của công cụ JS.
Kiến trúc JSI cho phép Fabric hoạt động với bất kỳ công cụ JavaScript nào — Hermes, JSC hoặc V8. Mã C++ của Fabric không phụ thuộc vào một triển khai công cụ JS cụ thể nào, giúp đơn giản hóa việc bảo trì và kiểm thử. Tất cả các thao tác UI — tạo, cập nhật, xóa — đều được thực hiện qua JSI, đảm bảo độ trễ tối thiểu.
// Đường ống kết xuất C++ của Fabric qua JSI
void mountShadowNode(
jsi::Runtime& runtime,
const ShadowNode::Shared& shadowNode,
const ShadowNode::SharedList& children
) {
auto props = shadowNode->getProps();
auto state = shadowNode->getState();
// Truyền props đồng bộ qua JSI
jsiValue.asObject(runtime)
.getProperty(runtime, "style")
.asObject(runtime);
// Tính toán bố cục trực tiếp qua Yoga
auto layoutMetrics =
YogaLayoutableShadowNode::layout(children);
// Áp dụng các thay đổi lên UI gốc
UIManager::synchronouslyUpdateViewOnUIThread(
shadowNode->getTag(), layoutMetrics
);
}
Lợi thế chính là cập nhật đồng bộ. Trong kiến trúc cũ, UI được cập nhật qua hàng đợi bất đồng bộ: React gửi lệnh qua Bridge, Shadow Thread xử lý bố cục, Native Thread kết xuất. Trong Fabric, tất cả các bước được thực hiện tuần tự trong một lần duy nhất. Điều này loại bỏ các điều kiện cạnh tranh và đảm bảo UI khớp với trạng thái hiện tại của ứng dụng.
Việc di chuyển lên Fabric không yêu cầu viết lại các thành phần React — tất cả các thành phần React Native hiện có tiếp tục hoạt động. Tuy nhiên, các thư viện có mã gốc (Native Module, ViewManager tùy chỉnh) có thể cần cập nhật. Meta khuyên bạn nên kiểm tra tính tương thích của từng thư viện trước khi bật kiến trúc mới.
Để bật Fabric trong dự án React Native 0.76+, đặt cờ newArchEnabled: true trong react-native.config.js. Fabric sẽ tự động bật cùng với Turbo Module. Nếu có sự cố, có thể tắt Fabric bằng cách quay lại trình kết xuất cũ mà không cần thay đổi mã ứng dụng — cả hai kiến trúc đều được hỗ trợ song song.
// package.json — kiểm tra thư viện tương thích 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"
Khi di chuyển, điều quan trọng là cập nhật tất cả các thư viện gốc lên phiên bản tương thích với Fabric. Các thư viện chính như react-native-reanimated và react-native-gesture-handler đã hỗ trợ kiến trúc mới. Đối với các thư viện chưa được cập nhật, Fabric cung cấp cơ chế tương thích — nếu một thư viện không hỗ trợ Fabric, trình kết xuất sẽ tự động quay về trình cũ cho thư viện đó.
Câu hỏi thường gặp
Có, từ Expo SDK 52, kiến trúc mới được bật theo mặc định. Fabric và Turbo Modules có sẵn trong managed workflow mà không cần cấu hình thêm.
Fabric cải thiện đáng kể hoạt ảnh nhờ kết xuất đồng bộ. Các hoạt ảnh trên luồng JS không còn cạnh tranh với xử lý thông điệp Bridge, loại bỏ tình trạng giật lag và tụt FPS.
Không, tất cả các thành phần React Native tiêu chuẩn đều hoạt động với Fabric mà không cần thay đổi. Chỉ các thành phần ViewManager tùy chỉnh mới cần cập nhật để hỗ trợ kiến trúc mới.
Đặt newArchEnabled: false trong react-native.config.js và xây dựng lại ứng dụng. Tất cả các mô-đun và thành phần sẽ tiếp tục hoạt động mà không cần thay đổi — Fabric và trình kết xuất cũ hoàn toàn có thể thay thế cho nhau.
Chế độ bridgeless là chế độ hoạt động của Fabric trong đó Bridge bị tắt hoàn toàn. Tất cả giao tiếp chỉ diễn ra qua JSI, mang lại hiệu suất tối đa. Có sẵn trong React Native 0.76+.
Tổng kết
Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay
IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.
Đọc thêm