React Native 0.68 and “new architecture”

March 30, 2022 Meta Engineering Team announced new version of React Native 0.68. In addition to various minor improvements and fixes, this version contains a historical change for the platform, for the first time we can try the so-called new architecture in our applications. Let’s figure out together what kind of new architecture is and why it took almost 4 years to get to it.

How React Native Works

React Native is a set of tools, libraries and components that allow a developer to create applications with a native interface and logic running on a JS engine.

The following modules are responsible for building the application:

  • BUCK – multiplatform build system

  • metro bundler – JS builder written specifically for React Native

  • React Native CLI – a set of utilities for building an application for a specific platform

At runtime, the following are required:

  • js-core or Hermes – engines that run JS code

  • yoga layout – cross platform layout manager with syntax close to css flex box

  • ReactJS and React Native – application core, responsible for rendering on the JS side and interacting with the native layer

And so we put together the RN application. What happens under the hood?

Bridge based RN architecture
Bridge based RN architecture
  1. User clicks on the application icon

  2. Native Thread load all native dependencies and modules

  3. Native Thread starts JS Thread which loads the built js bundle

  4. The JS Thread sends a serialized message through Bridge about how to render the UI on the native side.

  5. Shadow Thread receives these messages and forms the UI Tree

  6. Based on the UI Tree, the Yoga layout manager generates native components with dimensions for a specific platform and device and passes them to the Native Thread for rendering

  7. Native Thread draws components on the screen. Below is an example of mapping RN components to platform-specific components.

User interaction follows the same pattern, Native Thread is responsible for processing gestures and sends information about the event through Bridge to JS Thread where the new UI state is calculated and the steps are repeated 4-7.

Problems of the old architecture

In 2018 RN team announced about the beginning of a great work on the creation of a new architecture. The main problem seemed to be asynchronous Bridge

  • a large number of events passing through the Bridge and requiring serialization / deserialization can serve as a bottleneck and cause slowness in the UI

  • the asynchronous nature of Bridge prevents it from being used effectively with synchronous native components

  • since communication between Native and JS happens via a message, JS can’t efficiently manage Shadow Thread directly since Shadow Thread doesn’t know anything about data structures on the JS side

New architecture

Schematically, the new architecture looks like this

You’ve probably noticed a lot of new names, let’s take a look at each of them.

JSI – JavaScript Interface replacement for Bridge. With JSI, you can directly interact with native modules, avoiding the overhead of message forwarding. Through JSI, native methods will be available to JavaScript through C++ host objects. These host objects can contain both independent functionality in C ++ and act as intermediaries for interacting with a native platform, for example, in Objective-c or Java via JNI. It is important that JSI methods can be both synchronous and asynchronous.

Fabric – a new rendering system that replaced UIManager. Thanks to JSI, now you do not need to keep a copy of the component tree on JS and Shadow thread and synchronize it through Bridge, but you can manipulate this tree directly. Fabric makes UI work synchronous and also prioritizes UI tasks over asynchronous calls such as HTTP requests or IO operations.

Turbo Modules – in the current architecture, all modules for working with native functionality (Bluetooth, Geo, Camera, etc.) must be loaded at application startup. In practice, this significantly slows down the application start time. Turbo Modules eliminate this problem and allow you to load native modules when you need them in your application. Another advantage is the use of JSI for communication between the module and JS.

codegen – simplifies the creation of native interfaces for working with Turbo Modules and Fabric. Using Flow or TypeScript, the module developer describes its interface, and the C++ code will be generated automatically.

Now, in the new scheme, JS Thread is much more directly integrated into different processes directly, you can communicate with several modules in parallel without waiting for a response in the form of a message through Bridge as it was before.

You can read more about how the new rendering works at on the React Native website in a special section.

How to use in practice?

In practice, to support the new architecture, we must ensure that all native modules work.

Inside React Native, all components already support the new architecture, and if you are going to create a new application or just want to experiment with a new architecture, then this guide will be helpful.

If you are a developer of RN libraries or you have your own native modules, then following this manual you will be able to adapt your library. The following libraries can serve as a good example of the implementation of the new architecture:

What about existing applications? My feeling is that it will take another 6 to 12 months for the library developers to adapt them to the new architecture. One thing can be said unequivocally – this new architecture is the reality in which we are already. Do not ignore it, help the community, experiment and it will positively affect both your project and your experience with React Native.

Useful materials

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *