Fabric is the new rendering system in React Native's new architecture which has replaced the current UI manager. To understand it in more depth, let's look at how UI is rendered in the current architecture.
Current Architecture
Presently, React Native renders in the following sequence
React native code -> React Shadow Tree -> Bridge -> Native UI
Three threads are used by React Native:
- UI thread - It has access to the user interface. In other terms, it is the only thread that can manipulate the UI. Also, it is the main thread on which the application runs.
- Shadow thread - It is the background thread that is responsible for calculating all the layout dimensions and position.
- JS thread - It is the place where our react native code is executed. It contains all the business logic.
Working:
JS threads contain the code for creating a layout. Here is a sample code snippet.
<View style={{justifyContent: "center", alignItems: "center"}}>
<Text>Hello world!</Text>
</View>
The host(Android/iOS) has its own layout implementation and doesn't follow the flexbox code that we just wrote. Therefore, React Native converts the code into a layout system that the host operating system understands.
The Shadow thread
calculates all layout dimensions and positions and constructs a tree of the layout using the code in the JS thread
. In the Shadow thread
, React Native uses a layout engine called Yoga
which handles the conversion of the flexbox-based layout into a layout system that your native operating systems can understand.
React Native bridge is responsible for communicating the information from the JS thread
to the Shadow thread
. On the Shadow thread
, the data gets serialized and on the Main thread
, the data gets deserialized.
Problems:
- All communications are
asynchronous
which is good in most cases, but there is no way to update the datasynchronously
. For example, the Android RecyclerView's Adapter needs synchronous access to the data it is rendering to avoid flickering of the screen. That's why when we useFlatlist
with a large list of data, sometimes we see a white screen when we do a fast scroll. - It's slow to transfer large chunks of data through the bridge. For eg. An image that needs to be converted into a
base64
string. - When we scroll through a
Flatlist
with a huge list of data, we often feel apps are laggy as it drops the frames which is because the JS and UI threads are not in sync.
Introducing Fabric
In order to bridge the gap between React Native application user experience and native app experience, the Meta community has released a new renderer for React Native, called Fabric. The JSI
will directly expose native methods to JavaScript, including UI methods. The JS and UI threads can now be in sync as a result.
In general, the new rendering order will be
React Native Code -> Native -> Shadow Tree (C++) -> Native UI
To understand better, let's see how modern browsers handle the native call
When you invoke functions like document.getElementById
, they do not execute any JavaScript code. Instead, these functions are linked directly to native C++ code which get's called. Modern browsers do not let the JS layer communicate with the host Operating System using bridging, but instead, it does so using native code as we can see in the above image.
To summarize, fabric eliminates the bridge and lets the UI be controlled directly by the JS thread using react native code.
Benefits of fabric:
- User interactions can be prioritized to be executed synchronously in the main thread or native thread. For example, scrolling and gestures.
- The new
Shadow Tree
can be shared between the JS and UI threads, for allowing straight interaction from both ends. - The new rendering system improves the transfer of data by accessing JavaScript values directly using JavaScript Interfaces (JSI).
- The new rendering system is cross-platform, so it is easier to keep consistency among different platforms.
That’s it from this article. You can read more about it here.