React Native

    React-native new architecture

    Published
    April 19, 2023
    Reading Time
    3 min read
    Author
    Felix
    Access
    Public

    1. React-native style

    In the last article, we should already have a certain concept of cross-platform, but there is actually a problem that has not been solved here, that is, the styles on ios and Android are actually different, so our Rn needs to smooth out this difference. rn uses css-in-js.

    The style object we write in js will be processed by a separate thread, which is the Shadow thread. In this thread, the Yoga engine (which is also developed by Facebook) recalculates the layout of app. After calculating the things about app, this engine feeds the results back to the UI thread and finally presents them.

    Then the architecture of a complete old version is like this:

    image.png

    Then let’s sort out the whole process now: Suppose we now have a piece of react code

    <View style={{width: 200, height: 200}}/>
    
    

    The next step is for the js thread to serialize it

    UIManager.createView([352,"RCTView",191,{width":200,"height":200}])
    
    
    

    At this time, this task enters the asynchronous queue in front of the bridge, and its destination is ShadowThread. After receiving this information, ShadowTread first deserializes it to form a Shadow tree, and then passes it to Yoga to form the native layout information.

    The next step is to serialize the information and pass it to the native thread, and then deserialize it to render and draw based on the layout information.

    Everyone should now have a basic understanding of the overall architecture of an rn. Do you still remember the question in the last article? Loads and async of bridge can cause performance issues and uncertainty.

    • The transmission of thread information needs to be serialized repeatedly every time to reduce overhead, but serialization is a very expensive thing.

    • The uncertainty of asynchronous queues, you cannot guarantee the order of an event.

    Therefore, the new architecture of rn is to solve these problems, which is the current middle layer.

    2. React-native new architecture

    There is a lot of content about the new architecture, and I may not understand it properly in some places. I welcome your corrections.

    Let’s talk about the biggest change first, which is that rn directly killed the old bridge in the new architecture and directly replaced it with a new middle layer or general layer, which is JS Interface (JSI). There is a lot of new content in this general layer. We can take a look at this architecture diagram first.

    image.png

    So, let’s take a look at the changes. The middle part of the picture above is JSI. (Explain why this picture is like this, because I actually think Turbo Modules is an enhancement of Native Moodles, and Fabric is an enhancement of Renderer, they already exist).

    1. JS-bundle is no longer strongly dependent on the JavaScriptCore engine. We can now easily replace it with a better engine with better performance. For example Hermes.

    2. JSI allows us to call native methods directly in the js layer. Implemented by HostObject C++ object, it directly stores references to native layer methods and properties on a global object, and then our js can directly call java/oc api.

    3. The emergence of Turbo Modules (Native Mudles in the picture above). In the previous architecture, all Native Modules used by JS (such as Bluetooth, geolocation, file storage, etc.) must be initialized before the application is opened, which means that even if the user does not need some modules, it still must be initialized at startup.

    Turbo Modules are basically enhancements to these old Native modules. As mentioned before, now JS will be able to hold references to these modules, so JS code can only load the corresponding modules when needed, which can significantly shorten the startup time of RN applications.

    1. Fabric is the renderer in the picture above (previously the shadow layer was implemented in the native layer), a new UI renderer, which is equivalent to directly creating a ShadowTree in C++. One is faster and also reduces the steps of rendering elements.

    Maybe you don’t understand, for example: when App is running, React will execute your code and create a ReactElementTree in JS, based on this tree renderer will create a ReactShadowTree in C++. Fabric will use Shadow Tree to calculate the position of UI elements, and once Layout is completed, Shadow Tree will be converted into HostViewTree composed of Native Elements (for example: in RN will become ViewGroup in Android and UIView in iOS).

    1. codegen is actually a static type checker. CodeGen uses typed JavaScript to define interface elements for Turbo Modules and Fabric for their use, and it will generate more native code at compile time instead of runtime.

    3. Rendering of RN

    Rendering React code to the host platform is called the rendering pipeline, which can be roughly divided into three stages:

    • Rendering (Render): In JavaScript, React executes the business logic code to create React element trees (React Element Trees). Then in C++, use the React element tree to create a React shadow tree (React Shadow Tree).

    • Commit (Commit): After the React shadow tree is completely created, the renderer will trigger a commit. This will promote the React element tree and the newly created React shadow tree to the "next tree to mount". This process also includes layout information calculation.

    • Mount (Mount): After the React shadow tree has the layout calculation result, it will be converted into a host view tree (Host View Tree).

    4. Some basic libraries

    Ok, the above is all about the architectural design of the framework. We first have a general concept, and now we get a little closer to the actual practice to understand some necessary packages, because we won’t talk about it later.

    React-native only has some necessary built-in packages, but in order to reduce the size of the package as much as possible, many packages need to be configured by yourself, such as asyncStorage. For this kind of sdk, you need to rely a little bit on related native knowledge, but it is not a big problem. Generally, there will be a template to teach you, just follow the template (but not necessarily, in most cases). So let’s take a look at some commonly used packages now.

    3.1, React Navigation

    This should be something that almost every student who uses rn should understand. The routing of native app and web are different. In app, there is actually no concept of url. In native screen, you need to understand screen, which means to control the screen that the user sees. In the old version of rn there were some primitive navigation components to control the screen, but they were very complicated, so now the library react-navigation is generally used.

    Let me go straight to the actual combat.

    import * as React from "react";
    
    import { NavigationContainer } from "@react-navigation/native";
    
    import { createNativeStackNavigator } from "@react-navigation/native-stack";
    
    import Home from "./Home";
    
    import Settings from "./Settings";
    
    const Stack = createNativeStackNavigator();
    
    export default function App() {
    
    return (
    
        <NavigationContainer>
    
            <Stack.Navigator>
    
                <Stack.Screen name="Home" component={Home} />
    
                <Stack.Screen name="Settings" component={Settings}/>
    
            </Stack.Navigator>
    
        </NavigationContainer>
    
    );
    
    }
    
    

    createNativeStackNavigator is a method to create your navigation component. It returns an object with two components, Screen and Navigator, which are used to configure navigation.

    import React from "react";
    
    import { View, Text, Button, StatusBar } from "react-native";
    
    import styles from "./styles";
    
    export default function Home({ navigation }) {
    
    return (
    
    <View style={styles.container}>
    
    <StatusBar barStyle="dark-content" />
    
    <Text>Home Screen</Text>
    
    <Button
    
    title="Settings"
    
    onPress={() => navigation.navigate("Settings")}
    
    />
    
    </View>
    
    );
    
    }
    
    

    Just see the home component. When you press it, it will jump to the settings screen. We will talk about more content later in the actual combat. It is just a simple demonstration.

    3.2 RN component library

    antd mobile estimates that in China we basically use this or our own packaged component library. We recommend several other NativeBase, React Native Element, UI Kittern, React-native-paper

    3.3 Start page

    In fact, the startup page is the transition page displayed before your js thread starts, React-native-bootsplash.

    3.4 Icon

    react-native-vector-icons, react-native-svg.

    3.5 Exception catching

    Normally, when we develop a web application, we handle errors well because they don't go outside the scope of JS. Simply put, our front-end is the king (control) of the web. We can easily see the reason and open the log in DevTools.

    But Rn is because in addition to the JS of the environment, we also have native components, which may also cause errors in app execution. So when an error occurs, our application will shut down immediately and it is difficult to figure out the reason, so React-native-exception-handler is also the package to solve this problem.

    Like this:

    import { setJSExceptionHandler, setNativeExceptionHandler } from "react-native-exception-handler";
    
    setJSExceptionHandler((error, isFatal) => {
    
    //…
    
    });
    
    const exceptionhandler = (exceptionString) => {
    
    //Exception handling code
    
    };
    
    setNativeExceptionHandler(
    
    exceptionhandler,
    
    forceAppQuit,
    
    executeDefaultHandler
    
    );
    
    

    3.6 package update

    In fact, if it is iOS and we want to update the application and upload it to the store, there is such a technology OAT that can replace the js package, you can look at Microsoft's Codepush

    4. End

    rnChinese document address, these two articles are all about some basic theoretical things. For some component APIs, you can read the documentation. Woo! Do you want to be strong? Then come and learn together, ->Look at the boiling point here.

    Comments

    Join the conversation

    0 comments
    Sign in to comment

    No comments yet. Be the first to add one.