Fabric — to nowy renderer React Native, całkowicie przepisany w C++ i zintegrowany z JSI. Zastąpił on stare renderowanie oparte na UIView i ViewManager, zapewniając synchroniczne aktualizacje UI i efektywne obliczanie zmian przez Shadow Tree. Według Meta Engineering Blog, 2024, Fabric jest obowiązkowym komponentem nowej architektury i jest dostępny w React Native 0.76+.
Najważniejsze
Fabric — to nowy system renderowania dla React Native, który zastąpił stary renderer działający przez Shadow Thread i Bridge. W starej architekturze proces renderowania obejmował trzy kroki: JavaScript obliczał Virtual DOM, Shadow Thread (Yoga) obliczał layout, Native Thread renderował UIView. Fabric łączy wszystkie te kroki w jednym potoku C++, działającym synchronicznie.
Rozwój Fabric rozpoczął się w 2019 roku jako część inicjatywy Lean Core i projektu „Nowa Architektura". Głównym celem było rozwiązanie problemów wydajnościowych związanych z asynchronicznym renderowaniem trójfazowym. W starej architekturze każda zmiana stanu wymagała trzech przejść przez różne wątki, co powodowało opóźnienie między zmianą danych a renderowaniem UI.
Fabric opiera się na koncepcji niezmiennego cieniowanego drzewa (Immutable Shadow Tree). Każdy węzeł drzewa reprezentuje komponent React z jego właściwościami i stanem. Przy zmianie stanu tworzone jest nowe drzewo, a Fabric oblicza różnicę między starym a nowym drzewem i stosuje tylko niezbędne zmiany w natywnym UI. Minimalizuje to liczbę operacji na UIView/ViewGroup i skraca czas renderowania.
Shadow Tree — to podstawa działania Fabric. W przeciwieństwie do starej architektury, gdzie Shadow Tree istniał tylko po stronie C++ i był oddzielony od drzewa JS przez asynchroniczny Bridge, Fabric tworzy w pełni zsynchronizowaną hierarchiczną reprezentację UI. Węzły Shadow Tree przechowują właściwości, stan i style komponentów, a Yoga oblicza layout bezpośrednio na poziomie C++.
Gdy komponent React aktualizuje swój stan, React Native wysyła nowy Shadow Node do Fabric. Fabric nie przerysowuje całego UI — używa algorytmu porównywania (diffing) na poziomie C++, aby określić, które węzły uległy zmianie. Tylko zmienione węzły są wysyłane do natywnego renderowania, co znacznie zmniejsza ilość pracy.
Proces renderowania w Fabric składa się z trzech faz, które są wykonywane synchronicznie na poziomie C++ bez przełączania wątków. Pierwsza faza — Render: React wywołuje funkcję renderowania komponentu, która zwraca React Element Tree. Druga faza — Commit: React Native tworzy nowe Shadow Tree i oblicza zmiany na podstawie starej wersji. Trzecia faza — Mount: Fabric stosuje zmiany w natywnym UI, tworząc, aktualizując lub usuwając UIView.
Wszystkie trzy fazy działają jako jeden potok, gdzie dane są przesyłane przez JSI bez serializacji. To kluczowa różnica w stosunku do starej architektury, gdzie między fazami występowały przerwy: JS → (JSON) → Shadow Thread → (layout) → Native Thread.
Porównanie Fabric ze starym rendererem pokazuje, jak znacząco zmieniła się architektura React Native. Stary renderer działał asynchronicznie, rozbijając proces renderowania na trzy niezależne wątki. Fabric łączy wszystko w jeden potok C++.
| Cecha | Stary renderer | Fabric |
|---|---|---|
| Architektura | Trzy wątki (JS, Shadow, Native) | Jeden potok C++ |
| Synchroniczność | Asynchroniczne renderowanie | Synchroniczne renderowanie |
| Shadow Tree | Zmienny, w każdym wątku własna kopia | Niezmienny, jeden wspólny |
| Kanały | Bridge + serializacja JSON | JSI + bezpośrednie wywołanie C++ |
| Wydajność | Opóźnienie do 16 ms na klatkę | Opóźnienie poniżej 1 ms na klatkę |
W praktyce Fabric jest szczególnie korzystny dla aplikacji z częstymi aktualizacjami UI: animacje, przewijanie z pływającymi nagłówkami, dane w czasie rzeczywistym. Dla statycznych stron (tekst, przyciski) różnica jest mniej zauważalna. Według benchmarków Meta, Fabric skraca czas renderowania początkowego ładowania listy o 40–60%.
JSI (JavaScript Interface) — to kluczowy komponent, który umożliwia działanie Fabric. Dzięki JSI Fabric uzyskuje bezpośredni dostęp do wartości JavaScript bez serializacji. Gdy React przekazuje właściwości do Fabric, nie są one kopiowane przez JSON — JSI przekazuje wskaźniki do danych w pamięci silnika JS.
Architektura JSI pozwala Fabric pracować z dowolnym silnikiem JavaScript — Hermes, JSC lub V8. Kod C++ Fabric nie zależy od konkretnej implementacji silnika JS, co upraszcza utrzymanie i testowanie. Wszystkie operacje na UI — tworzenie, aktualizacja, usuwanie — są wykonywane przez JSI, co gwarantuje minimalne opóźnienie.
// Potok renderowania C++ Fabric przez JSI
void mountShadowNode(
jsi::Runtime& runtime,
const ShadowNode::Shared& shadowNode,
const ShadowNode::SharedList& children
) {
auto props = shadowNode->getProps();
auto state = shadowNode->getState();
// Synchroniczne przesyłanie właściwości przez JSI
jsiValue.asObject(runtime)
.getProperty(runtime, "style")
.asObject(runtime);
// Obliczanie layoutu bezpośrednio przez Yoga
auto layoutMetrics =
YogaLayoutableShadowNode::layout(children);
// Zastosowanie mutacji do natywnego UI
UIManager::synchronouslyUpdateViewOnUIThread(
shadowNode->getTag(), layoutMetrics
);
}
Kluczową zaletą jest synchroniczna aktualizacja. W starej architekturze UI był aktualizowany przez asynchroniczną kolejkę: React wysyłał polecenie przez Bridge, Shadow Thread przetwarzał layout, Native Thread renderował. W Fabric wszystkie kroki są wykonywane sekwencyjnie w jednym przebiegu. Eliminuje to warunki wyścigu i gwarantuje, że UI odpowiada bieżącemu stanowi aplikacji.
Migracja na Fabric nie wymaga przepisywania komponentów React — wszystkie istniejące komponenty React Native nadal działają. Jednak biblioteki z kodem natywnym (Native Module, niestandardowe ViewManager) mogą wymagać aktualizacji. Meta zaleca sprawdzenie kompatybilności każdej biblioteki przed włączeniem nowej architektury.
Aby włączyć Fabric w projekcie React Native 0.76+, ustaw flagę newArchEnabled: true w react-native.config.js. Fabric włączy się automatycznie wraz z Turbo Module. W przypadku problemów Fabric można wyłączyć, wracając do starego renderera bez zmiany kodu aplikacji — obie architektury są obsługiwane równolegle.
// package.json — sprawdź biblioteki kompatybilne z 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"
Podczas migracji ważne jest zaktualizowanie wszystkich natywnych bibliotek do wersji kompatybilnych z Fabric. Duże biblioteki, takie jak react-native-reanimated i react-native-gesture-handler, już obsługują nową architekturę. Dla bibliotek, które jeszcze nie zostały zaktualizowane, Fabric zapewnia mechanizm kompatybilności — jeśli biblioteka nie obsługuje Fabric, renderer automatycznie przełącza się na stary dla tej biblioteki.
Często zadawane pytania
Tak, od Expo SDK 52 nowa architektura jest włączana domyślnie. Fabric i Turbo Module są dostępne w managed workflow bez dodatkowej konfiguracji.
Fabric znacznie poprawia animacje dzięki synchronicznemu renderowaniu. Animacje na wątku JS nie konkurują już z przetwarzaniem wiadomości Bridge, co eliminuje drgania i spadki FPS.
Nie, wszystkie standardowe komponenty React Native działają z Fabric bez zmian. Tylko niestandardowe ViewManager wymagają aktualizacji do obsługi nowej architektury.
Ustaw newArchEnabled: false w react-native.config.js i przebuduj aplikację. Wszystkie moduły i komponenty będą nadal działać bez zmian — Fabric i stary renderer są w pełni wymienne.
Bridgeless mode — to tryb pracy Fabric, w którym Bridge jest całkowicie wyłączony. Cała komunikacja odbywa się tylko przez JSI, co zapewnia maksymalną wydajność. Dostępny w React Native 0.76+.
Podsumowanie
Opracujemy aplikację mobilną pod klucz
IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.
Przeczytaj również