Lesson 18-React Native Core Architecture Design

React Native’s core architecture is designed to enable seamless collaboration between JavaScript and native platforms, achieving high-performance cross-platform mobile application development. Its architecture has evolved from a “Bridge-centric” model to the “Fabric + TurboModules” paradigm, progressively addressing core issues in communication efficiency, rendering performance, and developer experience. The following analysis explores this architecture from three dimensions: architectural layering, core modules, and design philosophy.

Architectural Layering Design

React Native’s architecture is divided into four layers, each with distinct responsibilities, achieving cross-platform collaboration through standardized interfaces:

JavaScript Application Layer

  • Responsibilities: Business logic, components, and state management code written by developers.
  • Key Technologies:
    • React Framework: Based on the Fiber architecture’s virtual DOM and reconciliation algorithm, responsible for declarative UI rendering and updates.
    • JSI (JavaScript Interface): A bridge for direct communication between JavaScript and native code (replacing the old Bridge), supporting synchronous calls and memory sharing.

Communication Layer

  • Old Bridge (gradually phased out):
    • Asynchronous Serialized Communication: JS and native exchange data through JSON message queues, incurring serialization/deserialization overhead.
    • Cross-Thread Communication: JS and native threads are decoupled via message queues, but real-time performance is poor.
  • New JSI:
    • Direct Memory Access: JS and native share the same memory space, supporting synchronous calls (e.g., TurboModules).
    • Type Safety: Code generation (Codegen) creates type definitions at compile time, avoiding runtime type errors.

Native Platform Layer

  • Responsibilities: Translates JavaScript abstractions into platform-native UI and functionality.
  • Key Technologies:
    • Native Modules: Encapsulate platform-specific features (e.g., Bluetooth, sensors), exposed to JS via TurboModules.
    • Native Views: Directly render native components (e.g., UIView/Android View) through Fabric, bypassing Bridge serialization overhead.

Rendering Layer

  • Old Rendering Process:
    • Shadow Tree: The JS thread generates a virtual DOM, sent to the native thread via Bridge to create a Shadow Tree, which is then merged into the native view tree.
    • Performance Bottlenecks: Cross-thread communication and serialization cause rendering delays.
  • New Fabric Rendering:
    • Direct Rendering: The JS thread directly manipulates the native view tree via JSI, reducing intermediate conversions.
    • Incremental Updates: Only synchronizes changed component properties, avoiding full redraws.

Core Module Design

JavaScript Engine and JSI

  • JavaScriptCore (iOS) and Hermes (Android):
    • Hermes Engine: A JavaScript engine optimized by Facebook for React Native, supporting bytecode precompilation to reduce startup time and memory usage.
    • JSI Integration: JSI, as a C++-layer universal interface, allows JavaScript to directly call native module methods (e.g., TurboModules) without relying on the Bridge.

TurboModules (New Native Module Architecture)

  • Design Goals: Replace the old RCTBridgeModule to achieve type-safe, high-performance native module calls.
  • Implementation Principles:
    • Code Generation: Automatically generates C++ and Java/Swift interface code from TypeScript type definitions.
    • Lazy Loading: Modules are initialized on demand, reducing startup time.
    • Synchronous Calls: Direct access to native methods via JSI, avoiding asynchronous message queue delays.
  • Example:
// TypeScript Type Definition
type ToastModuleSpec = {
  show(message: string, duration: number): void;
};

// Auto-Generated C++/Java/Swift Code Implements Native Module

Fabric Rendering System

  • Core Components:
    • Shadow Tree: A lightweight layout description generated by the JS thread (no longer serialized to the native thread).
    • UI Manager: Directly manipulates the native view tree via JSI, enabling incremental updates.
  • Advantages:
    • Zero-Copy Rendering: JS and native share layout data, avoiding cross-thread communication.
    • Concurrent Rendering: JS and native threads can process layout and drawing in parallel, improving performance.

Component Lifecycle in the New Architecture

  • Mounting Process:
    1. The JS thread creates Fiber nodes via ReactReconciler.
    2. Fiber nodes notify the native thread through JSI to create corresponding native views.
    3. The native thread directly renders the views without waiting for Bridge messages.
  • Update Process:
    1. The JS thread calculates differences (Diffing) and generates update instructions.
    2. Instructions are sent directly to the native thread via JSI for partial view updates.

Design Philosophy and Evolution Logic

From Bridge to JSI: A Communication Revolution

  • Pain Points of the Old Bridge:
    • Asynchronous communication caused interaction delays (e.g., slow click event responses).
    • Serialization/deserialization consumed CPU and memory resources.
    • Cross-thread synchronization was complex, leading to performance bottlenecks.
  • JSI Solutions:
    • Synchronous Calls: Support operations with high real-time requirements (e.g., animations, gestures).
    • Memory Sharing: JS and native directly access the same data, avoiding copy overhead.
    • Type Safety: Compile-time type checking via Codegen reduces runtime errors.

Fabric Rendering System Performance Optimization

  • Issues with Old Rendering:
    • Serialization/deserialization of the Shadow Tree consumed significant time.
    • Cross-thread layout calculations caused frame rate drops.
  • Fabric Improvements:
    • Direct Rendering: JS and native threads collaborate, reducing intermediate steps.
    • Incremental Updates: Only synchronize changed components, avoiding full redraws.
    • Concurrent Mode: The JS thread can process multiple update tasks in parallel, improving throughput.

TurboModules Modular Design

  • Limitations of Old Native Modules:
    • Modules were initialized at startup, increasing launch time.
    • Lack of type safety required manual data conversion.
  • TurboModules Optimizations:
    • Lazy Loading: Modules initialize on demand, reducing startup time.
    • Code Generation: Automatically generates type definitions, minimizing manual coding errors.
    • Unified Interface: Dynamically registers and calls modules via TurboModuleRegistry.

Architecture Comparison: Old vs. New

DimensionOld Architecture (Bridge + ShadowTree)New Architecture (JSI + Fabric + TurboModules)
Communication MechanismAsynchronous Message Queue (JSON Serialization)Direct Memory Access (JSI Synchronous Calls)
Rendering ProcessShadow Tree Cross-Thread TransmissionJS Thread Directly Manipulates Native View Tree
Module CallsAsynchronous Interfaces Based on RCTBridgeModuleSynchronous/Asynchronous Interfaces Based on TurboModules
Performance BottlenecksCross-Thread Communication Delays, Serialization OverheadZero-Copy Communication, Concurrent Rendering
Developer ExperienceManual Type Conversion, Complex DebuggingType Safety, Auto-Generated Code

Future Evolution Directions

  1. Complete Bridge Removal: Gradually phase out the old Bridge, fully transitioning to JSI and Fabric.
  2. Multi-Threaded Rendering: Explore finer-grained division of labor among JS, UI, and native threads.
  3. Cross-Platform Component Library: Develop high-performance cross-platform UI components (e.g., animation and gesture libraries) based on the new architecture.
  4. Unified Web and Mobile: Achieve code reuse through React Native for Web, further reducing development costs.

React Native’s architectural evolution consistently focuses on “performance” and “developer efficiency.” The new architecture, through deep integration of JSI and Fabric, is redefining the boundaries of the cross-platform mobile development experience.

Share your love