RN 0.63 双端冷启动线程流转
RN 0.63 旧架构下Android 和 iOS 的冷启动都经历了相同的思路主线程入口 → 后台线程做重活创建引擎、加载 Bundle→ JS Thread 接管 → Shadow 计算布局 → 主线程渲染首帧。两端实现细节不同但线程模型一致。一、涉及的线程iOS4 条线程/队列线程/队列名称负责什么主线程Main ThreadAppDelegate 入口、RCTRootView 挂载、最终 UIKit 渲染后台初始化队列InitGCD background queue创建 JS 引擎、JS Thread、注册模块、加载 BundleJS 线程JS ThreadNSThread CFRunLoop执行 Bundle驱动后续 JS 逻辑布局计算队列Shadow QueueGCD serial queueYoga 布局计算生成 UIBlocksAndroid5 条线程线程名称负责什么主线程Main ThreadApp 入口、Activity 创建、ReactContext 挂载、最终 UI 渲染后台初始化线程Init ThreadAsyncTask创建 JS 引擎、Bridge、注册模块、加载 BundleJS 线程JS ThreadMessageQueueThreadBundle 执行完后启动负责所有后续 JS 逻辑布局计算线程Shadow ThreadYoga 计算布局构建 Shadow TreeUI 线程UI Thread将布局结果转成真实 Android View实际就是主线程二、iOS 冷启动流转┌──────────────────────────────────────────────────────────┐ │ 1. App 冷启动主线程 │ └──────────────────────────────────────────────────────────┘ │ ▼ ┌───────────────────────────────────────────────┐ │ AppDelegate.application:didFinishLaunching │ │ 创建 RCTBridge只是配置未启动 JS │ │ 创建 RCTRootView │ └───────────────────────────────────────────────┘ │ ▼ ┌───────────────────────────────────────────────┐ │ RCTRootView 触发 RCTBridge 开始初始化 │ │ → RCTBridge 内部创建 RCTCxxBridge │ └───────────────────────────────────────────────┘ │ ▼ ══════════════════ ✦ 切入后台队列GCD background ✦ ══════════════════ ┌──────────────────────────────────────────────────────────┐ │ 2. RCTCxxBridge 初始化后台 GCD queue │ └──────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────┐ │ a. 创建 JS 引擎JSC 或 Hermes │ └─────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────┐ │ b. 创建 JS Thread │ │ NSThread CFRunLoop 驱动 │ │ 线程名com.facebook.react.JavaScript │ └─────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────┐ │ c. 注册 NativeModules │ │ 扫描所有 RCTBridgeModule生成模块配置表 │ └─────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────┐ │ d. 加载 JS Bundle │ │ DevHTTP 读取 Metro │ │ ReleaseNSBundle mainBundle │ └─────────────────────────────────────────────┘ ══════════════════ ✦ 切到 JS Thread ✦ ══════════════════ ▼ ┌──────────────────────────────────────────────────────────┐ │ 3. 执行 JS BundleJS Thread │ │ - 定义所有模块 │ │ - 注册 ViewManagers │ │ - AppRegistry.registerComponent │ └──────────────────────────────────────────────────────────┘ │ ▼ ══════════════════ ✦ 切回主线程 ✦ ══════════════════ ┌──────────────────────────────────────────────────────────┐ │ 4. RCTBridge 通知 RCTRootView bridge 就绪主线程 │ │ → 调用 AppRegistry.runApplication │ │ → JS 开始描述 UI 结构 │ └──────────────────────────────────────────────────────────┘ │ ▼ ══════════════════ ✦ 切到 Shadow Queue ✦ ══════════════════ ┌─────────────────────────────────────────────┐ │ 5. RCTShadowView 布局计算Shadow Queue │ │ - 构建 Shadow Tree │ │ - Yoga 计算布局 │ │ - 生成 UIBlocks 放入 _pendingUIBlocks │ └─────────────────────────────────────────────┘ │ ▼ ══════════════════ ✦ 切回主线程 ✦ ══════════════════ ┌─────────────────────────────────────────────┐ │ 6. RCTUIManager flush UIBlocks主线程 │ │ - 创建 / 更新真实 UIKit View │ │ - 由 CADisplayLink 每帧触发 │ └─────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────┐ │ 7. RN UI 首帧渲染完成 │ └─────────────────────────────────────────────┘三、Android 冷启动流转┌──────────────────────────────────────────────────────────┐ │ 1. App 冷启动主线程 │ └──────────────────────────────────────────────────────────┘ │ ▼ ┌───────────────────────────────────────────────┐ │ Application.onCreate() │ │ 创建 ReactNativeHost仅配置不创建 RN 实例 │ └───────────────────────────────────────────────┘ │ ▼ ┌───────────────────────────────────────────────┐ │ Activity.onCreate() │ │ 创建 ReactRootView │ └───────────────────────────────────────────────┘ │ ▼ ┌───────────────────────────────────────────────┐ │ ReactRootView.startReactApplication() │ │ → 获取 ReactInstanceManagerRIM │ │ → RIM.createReactContextInBackground() │ └───────────────────────────────────────────────┘ │ ▼ ══════════════════ ✦ 切入后台线程Init Thread ✦ ══════════════════ ┌──────────────────────────────────────────────────────────┐ │ 2. ReactContextInitAsyncTask.run()后台线程 │ └──────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────┐ │ a. 创建 JS 引擎JSC 或 Hermes │ └─────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────┐ │ b. 创建 CatalystInstanceC Bridge │ │ JS ↔ C ↔ JNI ↔ Java 四层通信 │ └─────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────┐ │ c. 注册 NativeModules由 ReactPackage 提供 │ └─────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────┐ │ d. 加载 JS Bundle │ │ DevHTTP 读取 Metro │ │ Releaseassets://main.jsbundle │ └─────────────────────────────────────────────┘ │ ▼ ┌──────────────────────────────────────────────────────────┐ │ e. 执行 JS Bundle │ │ - 定义所有模块 │ │ - 注册 UIManager / ViewManagers │ │ - AppRegistry.registerComponent │ │ → JS Thread 启动MessageQueueThread │ └──────────────────────────────────────────────────────────┘ ══════════════════ ✦ 切回主线程 ✦ ══════════════════ ▼ ┌──────────────────────────────────────────────────────────┐ │ 3. RIM.setupReactContext()主线程 │ │ - 创建 ReactContext │ │ - 通知所有 ReactRootView attach │ │ - 触发 UIManager.createRoot │ └──────────────────────────────────────────────────────────┘ │ ▼ ══════════════════ ✦ 切到 Shadow Thread ✦ ══════════════════ ┌─────────────────────────────────────────────┐ │ 4. Yoga 布局计算Shadow Thread │ │ - 构建 Shadow Tree │ │ - 计算各节点尺寸和位置 │ └─────────────────────────────────────────────┘ │ ▼ ══════════════════ ✦ 切到 UI Thread主线程 ✦ ══════════════════ ┌─────────────────────────────────────────────┐ │ 5. UIManager 操作 Android View │ │ createView / updateView / manageChildren │ └─────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────┐ │ 6. RN UI 首帧渲染完成 │ └─────────────────────────────────────────────┘四、双端对比环节AndroidiOS应用入口Application.onCreate()Activity.onCreate()AppDelegate.application:didFinishLaunchingRN 根视图ReactRootViewRCTRootViewBridge 管理器ReactInstanceManagerRIMRCTBridgeBridge 实体CatalystInstanceJava JNI CRCTCxxBridgeObjC C无 JNI后台初始化方式AsyncTask后台 GCD queueJS Thread 驱动MessageQueueThreadLooper/HandlerNSThreadCFRunLoopNativeModule 注册ReactPackageRCTBridgeModule宏Shadow 计算Shadow Thread独立 Java 线程Shadow QueueGCD serial queueUI 更新UIManager→ Android ViewRCTUIManager→ UIKit ViewUI 帧驱动ChoreographerCADisplayLink通信层JS ↔ C ↔ JNI ↔ Java4层JS ↔ C ↔ ObjC3层无 JNIiOS 比 Android 少一层 JNI因为 ObjC 支持直接混编 C.mm文件不需要额外的跨语言桥接。五、名词解释ReactNativeHostAndroid 侧 RN 的全局配置容器工厂模式。只持有配置Bundle 路径、Dev 模式开关等不直接创建 RN 实例由ReactInstanceManager负责真正的初始化。ReactRootView / RCTRootViewRN 的根视图容器。Android 侧继承自FrameLayoutiOS 侧继承自UIView。作用一样作为 Native 布局和 RN 渲染内容的边界RN 渲染的所有组件都挂在它下面。ReactInstanceManagerRIMAndroid 侧 RN 实例的调度中心。负责创建 JS 引擎、管理ReactContext生命周期、协调各线程的初始化顺序。iOS 侧对应的是RCTBridge。ReactContextInitAsyncTaskAndroid 的AsyncTask子类专门把 RN 初始化的耗时工作创建引擎、加载 Bundle移到后台线程避免主线程被阻塞。CatalystInstance旧架构 Android 侧的 Bridge 核心实体负责 JS ↔ C ↔ JNI ↔ Java 四层通信。所有 JS 调 Native、Native 调 JS 都经过它且必须 JSON 序列化。新架构用 JSI 替掉了它。JNIJava Native InterfaceJava 调用 C/C 原生代码的桥接机制。因为 JS 引擎JSC/Hermes是 C 写的Android 业务层是 Java两者必须通过 JNI 跨语言调用。iOS 没有这层ObjC 可以直接混编 C。ReactPackageAndroid 侧注册 NativeModule 的方式。开发者实现ReactPackage接口并返回模块列表RN 初始化时统一扫描注册。iOS 侧用RCTBridgeModule宏替代自动注册不需要手动列举。JS BundleMetro 打包后的 JavaScript 产物main.jsbundle。包含所有业务代码和第三方库。Dev 模式从 Metro HTTP 服务实时拉取Release 模式预先打包进 App 资源目录。MessageQueueThreadAndroid 侧 JS Thread 的实现基于LooperHandler机制。是一个有消息队列的后台线程所有 JS 任务串行投递到这里执行。iOS 侧对应的是NSThreadCFRunLoop。ReactContextRN 的运行时容器持有 JS 执行环境、NativeModule 注册表、Bridge 实例等。可以理解为 RN 的全局上下文初始化完成后通知所有ReactRootView开始渲染。UIManager / RCTUIManager负责将 JS 描述的 UI 结构转换为真实 Native View 的管理器。接收来自 JS 的createView、updateView、manageChildren等指令在主线程操作真实 View。Shadow Tree / ShadowNode / RCTShadowViewRN 的虚拟布局树。每个 JS 组件对应一个 Shadow 节点存储布局属性宽高、padding、flex 等。布局计算在 Shadow Thread / Shadow Queue 中进行不占用主线程。YogaFacebook 开源的跨平台布局引擎实现了 CSS Flexbox 规范Android 和 iOS 共用同一套 C 实现。RN 在 Shadow Thread 中用 Yoga 计算每个节点的实际尺寸和位置。RCTBridge / RCTCxxBridgeiOS 侧的 Bridge 管理器RCTBridge及其 C 实现层RCTCxxBridge。RCTBridge是对外的 ObjC 接口RCTCxxBridge是真正执行初始化的 C 核心负责创建 JS 引擎、JS 线程、注册模块。RCTBridgeModuleiOS NativeModule 的注册协议。在 ObjC 类里加上RCT_EXPORT_MODULE()宏RN 初始化时自动扫描注册不需要像 Android 那样在ReactPackage里手动列举。_pendingUIBlocksRCTUIManager内部的待执行 UI 操作队列。Shadow Queue 计算完布局后把需要做的 View 操作封装成 Block 放进来等 CADisplayLink 触发时批量提交到主线程执行避免频繁切换主线程。CADisplayLink / Choreographer屏幕刷新率同步计时器。iOS 用CADisplayLinkAndroid 用Choreographer都是每帧~16.7ms触发一次驱动 RN 把_pendingUIBlocks批量提交到主线程更新 UI。六、与新架构的对比旧架构0.63的瓶颈主要集中在 Init Thread 这一段旧架构新架构改进CatalystInstance四层序列化通信JSIJS 直接持有 C 对象引用无序列化NativeModules 启动时全量注册TurboModules懒加载首次调用时才初始化Shadow Tree 可变需要线程锁FabricShadow Tree 不可变多线程安全不支持 React 并发特性Fabric 支持可中断渲染、优先级调度
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2489818.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!