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 и проекта „Нова Архитектура“. Основната цел беше решаване на проблемите с производителността, свързани с асинхронното трифазно рендиране. В старата архитектура всяка промяна на състоянието изискваше три преминавания през различни нишки, което създаваше забавяне между промяната на данните и рендирането на UI.
Fabric се основава на концепцията за неизменимо сенчесто дърво (Immutable Shadow Tree). Всеки възел на дървото представлява React компонент с неговите props и състояние. При промяна на състоянието се създава ново дърво и Fabric изчислява разликата между старото и новото дърво и прилага само необходимите промени към родния UI. Това минимизира броя на операциите с UIView/ViewGroup и съкращава времето за рендиране.
Shadow Tree — е основата на работата на Fabric. За разлика от старата архитектура, където Shadow Tree съществуваше само от страната на C++ и беше отделен от JS дървото чрез асинхронен 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 без сериализация. Това е ключовата разлика от старата архитектура, където имаше прекъсвания между фазите: JS → (JSON) → Shadow Thread → (оформяне) → Native Thread.
Сравнението на Fabric със стария рендерер показва колко значително се е променила архитектурата на React Native. Старият рендерер работеше асинхронно, разделяйки процеса на рендиране на три независими нишки. Fabric обединява всичко в един C++ конвейер.
| Характеристика | Стар рендерер | Fabric |
|---|---|---|
| Архитектура | Три нишки (JS, Shadow, Native) | Единен C++ конвейер |
| Синхронност | Асинхронно рендиране | Синхронно рендиране |
| Shadow Tree | Променливо, собствено копие на всяка нишка | Неизменимо, единно |
| Канали | Bridge + JSON сериализация | JSI + директно C++ извикване |
| Производителност | Закъснение до 16 ms на кадър | Закъснение под 1 ms на кадър |
На практика Fabric е особено полезен за приложения с чести обновявания на UI: анимации, скрол с плаващи заглавни части, данни в реално време. За статични страници (текст, бутони) разликата е по-малко забележима. Според бенчмарковете на Meta, Fabric намалява времето за рендиране на началното зареждане на списък с 40–60%.
JSI (JavaScript Interface) — е ключовият компонент, който прави Fabric възможен. Чрез JSI Fabric получава директен достъп до JavaScript стойности без сериализация. Когато React предава props на Fabric, те не се копират чрез JSON — JSI предава указатели към данни в паметта на JS двигателя.
Архитектурата на JSI позволява на Fabric да работи с всеки JavaScript двигател — Hermes, JSC или V8. C++ кодът на Fabric не зависи от конкретната имплементация на JS двигателя, което опростява поддръжката и тестването. Всички операции с UI — създаване, обновяване, изтриване — се изпълняват чрез JSI, което гарантира минимално закъснение.
// Fabric C++ конвейер за рендиране чрез JSI
void mountShadowNode(
jsi::Runtime& runtime,
const ShadowNode::Shared& shadowNode,
const ShadowNode::SharedList& children
) {
auto props = shadowNode->getProps();
auto state = shadowNode->getState();
// Синхронно предаване на props чрез 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 нишката вече не се конкурират с обработката на съобщения на 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 г. Ще ви консултираме и ще предложим най-доброто решение.
Прочетете също