I. History: React Native from Beginning to Now
React Native's positioning is building native apps through React:
A framework for building native apps with React.
It has 5 major characteristics:
-
Create native apps for Android and iOS using React: Use React to create Android, iOS applications
-
Written in JavaScript—rendered with native code: What you write is JavaScript, what actually renders is Native interface
-
Native Development For Everyone: Develop based on platform-agnostic basic components to obtain platform native experience
-
Seamless Cross-Platform: Seamless transition, Native code can be wrapped as components usable by React Native
-
Fast Refresh: Changes take effect immediately, having Web-like development speed
So, there are 2 questions:
-
Why use React (or JavaScript) to write Native applications? What's the driving force?
-
Why cross-platform in this way, instead of WebView?
Exploration Approach
There are 2 reasons for using React to write Native applications:
-
React's own advantages: UI predictability from declarative view definitions, complexity decomposition under componentization mechanism, etc.
-
Web development advantages: Fast iteration, fast feedback, fast development
If Native uses React, it can also gain React's various benefits. Of course, this is just one aspect; the real driving force behind is the hope that Native development can move fast like Web.
For the second question, we need to start from the origin of React Native.
Actually, Facebook tried 3 approaches:
-
WebView: Native provides Webview container, business uses Web technology for development
-
Porting React to native: Port React to Native implementation
-
Scripting native: Call Native API through JavaScript
Not using low-cost WebView solution for cross-platform is because limited by Web technology, experience cannot compare with Native, ultimately abandoned because performance and scalability didn't meet expectations.
Porting React to Native is a good approach, but can only gain some of React's own benefits (not including React's prosperous ecosystem in JavaScript world), and doesn't help Native's move fast, because Native is still pure Native.
In comparison, React Native calling Native API through JavaScript is a win-win solution,既能 let Native use React (and JavaScript's prosperous ecosystem), and also have Web's development speed, because what's written and actually executed are both JavaScript, Native only provides view rendering capabilities and platform-specific capabilities.
Development History
React Native was born in 2013 at Facebook's internal hackathon.

At React.js Conf in January 2015, this internal project was first announced, and officially open-sourced at F8 Conference in May. Initially only supported iOS, supported Android in September of the same year.
Microsoft UWP and Samsung Tizen support provided in 2016 means React Native moved from mobile to PC (Win 10), game consoles (Xbox One), smartwatches (Gear Fit 2), smart TVs (SUHD) and even holographic glasses (HoloLens).
Architecture upgrade plan Fabric was launched in June 2018, refactoring thread model and simplifying React Native Core to better support Native & React Native hybrid apps.
JavaScript engine-level performance improvement came in July 2019, replacing JavaScriptCore previously used on Android platform with Hermes.
P.S. For more information about React Native development history, see A Brief History of React Native
II. Architecture: So, This is What RN Is Like!
What you write is JavaScript, what actually renders is Native interface
Therefore, from a very high perspective, React Native technology (or Scripting Native solution) can be understood like this:
JavaScript Layer
---------------------------------
???
---------------------------------
Native Layer
The key point is: What's in the middle? How are the upper and lower worlds connected?
Architecture Design
In React Native, the middle is Bridge layer, connecting JavaScript world and Native world through message communication.
Specifically, Shadow Tree is used to define UI effects and interaction features, Native Modules provide Native capabilities (such as Bluetooth), and they communicate with each other through JSON messages:

Bridge layer is the key to React Native technology, with 3 design characteristics:
-
Asynchronous: Doesn't rely on synchronous communication
-
Serializable: Ensures all UI operations can be serialized to JSON and converted back
-
Batched: Queues Native calls, processes in batches
P.S. For more information about React Native architecture, see React Native Architecture Overview
Thread Model

There are mainly 3 threads in React Native:
-
UI Thread: Main thread in Android/iOS (or other platform) applications
-
Shadow Thread: Thread for layout calculations and constructing UI interface
-
JS Thread: React and other JavaScript code all execute in this thread
Additionally, there's a category of Native Modules threads, different Native Modules can run in different threads (see Threading for details)
Startup Process
Overall, startup process is divided into two parts: initializing Bridge and executing business code, corresponding to upper and lower parts in the diagram:

Rendering Mechanism

During first render (process from right to left in diagram), JS thread passes view information (structure, style, properties, etc.) to Shadow thread, creates Shadow Tree for layout calculations. After Shadow thread calculates layout, it passes complete view information (including width, height, position, etc.) to main thread, which creates Native View based on this.
During user interaction (process from left to right in diagram), main thread first packages relevant information into event messages and passes to Shadow thread, then generates specified events for corresponding elements based on mapping relationship established by Shadow Tree, finally passes events to JS thread to execute corresponding JS callback functions.
Architecture Evolution
Original design also brought some limitations:
-
Asynchronous: Cannot directly integrate JavaScript logic with many Native APIs that need synchronous answers
-
Batched: Very difficult for React Native applications to call functions implemented by Native
-
Serializable: Exists unnecessary copy, instead of directly sharing memory
These problems are especially prominent in Native + React Native hybrid applications, therefore, large-scale architecture upgrade plan was proposed in June 2018:

Specifically includes 3 major changes:
-
JavaScript Layer: Introduce JSI, allowing replacement of different JavaScript engines
-
Bridge Layer: Divide into Fabric and TurboModules parts, responsible for UI management and Native modules respectively
-
Native Layer: Streamline core modules, split non-core parts out as community modules for independent update and maintenance
Fabric expects to simplify complex cross-thread interactions in rendering process, allowing JavaScript to directly control high-priority UI operations, even allowing synchronous calls (handling scenarios like fast list scrolling, page switching, gesture processing, etc.)
TurboModules allows on-demand loading of Native modules, and directly holds their references after module initialization, no longer relying on message communication to call module functions.
P.S. For more information about React Native architecture upgrade, see React Native Architecture Evolution
III. Ecosystem: Learn once, write anywhere?
React Native's original vision is learn once, write anywhere:
It's worth noting that we're not chasing "write once, run anywhere." Different platforms have different looks, feels, and capabilities, and as such, we should still be developing discrete apps for each platform, but the same set of engineers should be able to build applications for whatever platform they choose, without needing to learn a fundamentally different set of technologies for each. We call this approach "learn once, write anywhere."
(From React Native: Bringing modern web techniques to mobile)
Application Ecosystem
In terms of platform support, currently (2019/9/21), besides official Android, iOS support, community also provides UWP, Tizen, Web, Mac, Apple TV, even WeChat Mini Program support.
P.S. For more supported platforms, see Out-of-Tree Platforms
In terms of enterprise applications, besides Facebook, React Native is also used in large-scale enterprises like Tencent, Baidu, JD.com:
-
Tencent: QQ Zone, Tencent Classroom
-
Baidu: Mobile Baidu
-
JD.com: JD App
Tool Ecosystem
In the 4 years since React Native's development, tool ecosystem has also developed to a certain extent:
-
Development tools: Nuclide (officially provided but no longer maintained), deco-ide, and Visual Studio Code, Webstorm, Sublime Text, ATOM and other mainstream IDEs all support React Native
-
Animation: lottie-react-native, react-native-animatable etc.
-
UI Components: NativeBase, React Native Elements etc.
-
Debugging tools: Chrome developer tools, Reactotron
P.S. For more information about React Native ecosystem, see Exploring React Native Ecosystem – Tools, backend, database and best libraries
Compared to deeply accumulated Android, iOS technology ecosystems, React Native ecosystem is still at a lower maturity stage, thus facing difficulties like Native infrastructure integration, cross-language stack debugging. But anyway, the vision of Learn once, write anywhere is on the way, coming towards us.
No comments yet. Be the first to share your thoughts.