React Native 架构原理

为了更好的理解 React Native,我们需要了解 RN 的架构原理。这里主要介绍两个内容

  • 现有架构
    当前 RN 正在使用的架构
  • 新架构
    2018年6月,Facebook推出了 RN 的重构计划。我们需要了解下一代 RN 的架构原理。

现有架构

架构模型
基本架构模型如下:

  • Native 是原生部分,例如:iOS 原生或 Android 原生
  • JS 端主要是 React 语法
  • Bridge 用与 Native 和 JS 的通信
  • 因为 Native 和 JS 相对独立。彼此通信是通过桥接器(Bridge)来实现。

React Native 架构原理_第1张图片
详细一点的架构模型
React Native 架构原理_第2张图片

  • 最上层提供类 React 支持,运行在 JSC 提供的 JavaScript 运行时环境中
  • Bridge 层将 JavaScript 与 Native 世界连接起来。具体的,
    Shadow Tree 用来定义 UI 效果及交互功能,
    Native Modules 提供 Native 功能(比如蓝牙),
  • 二者之间通过 JSON 消息相互通信

线程模型

  • JS 线程
    • JS 代码的执行线程,将源码通过 Metro 打包后,传给 JS 引擎进行解析
  • Main 线程(也称为 UI 线程或原生线程)
    • 主要负责原生渲染(Native UI)和调用原生模块(Native Modules)
  • Shadow 线程(也称为 Layout 线程)
    • 创建 Shadow Tree 来模拟 React 结构树(类似虚拟 DOM)
    • 再由 Yoga 引擎将 Flexbox 等样式,解析成原生平台的布局方式

    RN使用 Flexbox 布局,但是原生是不支持,Yoga 用来将 Flexbox 布局转换为原生平台的布局方式。

渲染机制

  • JS 线程将视图信息(结构、样式、属性等)传递给 Shadow 线程,
  • 创建出用于布局计算的 Shadow Tree,Shadow 线程计算好布局之后,再将完整的视图信息(包括宽高、位置等)传递给主线程
  • 主线程据此创建 Native View(UI)
    React Native 架构原理_第3张图片
    也可以通过下图,来理解渲染过程:
    React Native 架构原理_第4张图片

线程间通信
React Native 架构原理_第5张图片
现有架构启动流程
React Native 架构原理_第6张图片

新架构

新旧架构对比
React Native 架构原理_第7张图片
新架构的主要改动

  • JavaScript 层:
    • 支持 React 16+ 的新特征增强
    • JS 静态类型检查(CodeGen)
    • 引入 JSI,允许替换不同的 JavaScript 引擎。支持 JS 与 Native 直接通信
  • Bridge 层:
    • 划分成 Fabric 和 TurboModules 两部分,分别负责 UI 管理与 Native 模块
  • Native 层:
    • 精简核心模块,将非核心部分拆分出去,作为社区模块,独立更新维护

增强类型检查

  • CodeGen 是 FaceBook 推出的代码生成工具
    通过 CodeGen,自动将 Flow 或者 TypeScript 等有静态类型的 JS 代码翻译成 Fabric 和TurboModules 使用的接口文件。
  • 加入类型约束后的作用:
    • 减少了数据类型错误
    • 减少了数据验证的次数,提高了通信性能

举个例子:JS 中的数字经常被引号引起来,从而将数字类型转成了字符串。将转换后的数字传递给 bridge 的时候,通常 iOS下会静默失败,而 Android 会崩溃。

另外。类型约束对通信性能也有一定提升。因为,在加入类型约束之前,每次通信都需要进行数据验证。加载类型约束之后,我们就没有必要每次通信都进行数据验证了。减少了数据验证的次数,就会提高通信性能。

JSI(JavaScript Interface)
不同于之前直接将 JavaScript 代码输入给 JSC,新的架构中引入了一层 JSI(JavaScript Interface),作为 JSC 之上的抽象
React Native 架构原理_第8张图片

  • JSI 是一个用C++写成的轻量级框架。其作用主要有两个:
    • 通过 JSI,可以实现 JS 引擎的更换
    • 通过 JSI,可以通过 JS 直接调用 Native
      • JS 对象可以直接获得 C++ 对象(Host Objects)引用,从而允许 JS 与 Native 的直接调用
      • 减少不必要的线程通信
      • 省去了序列化和反序列化的成本
      • 减轻了通信压力,提高了通信性能

优化 Bridge 层

  • Fabric

    • 简化了 UI 渲染

    Fabric 简化了 React Native 渲染,简化之前渲染流程中,有复杂跨线程交互(React -> Native ->Shadow Tree -> Native UI)。优化之后,直接在 C++ 层创建 JavaScript 与 Native 共享的Shadow Tree,并通过 JSI 层将 UI 操作接口暴露给 JavaScript,允许 JavaScript 直接控制高优先级的 UI 操作,甚至允许同步调用(应对列表快速滚动、页面切换、手势处理等场景)。这样避免了跨线程的操作,极大地提高了UI的响应速度。

  • Turbo Modules

    • 通过 JSI,可以让 JS 直接调用 Native 模块,实现同步操作
    • 实现 Native 模块按需加载,减少启动时间,提高性能

    之前所有 Native Modules(无论是否需要用到)都要在应用启动时进行初始化,因为 Native 不知道 JS 将会调用哪些功能模块。而新的 Turbo Modules 允许按需加载 Native 模块,并在模块初始化之后直接持有其引用,不再依靠消息通信来调用模块功能。因此,应用的启动时间也会有所提升

精简核心(Lean Core)

  • 将 react-native 核心包进行瘦身
    • RN 推出多年,其核心包太过臃肿
    • 有些包在项目中用不到,每次也要引入,造成资源浪费
  • 非必要的包,移到社区模块,单独维护
    • 例如:AsyncStorage、WebView 等

新架构启动流程
React Native 架构原理_第9张图片

你可能感兴趣的:(笔记,泛客户端开发,react,native)