问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

React Native原理简要介绍

创作时间:
作者:
@小白创作中心

React Native原理简要介绍

引用
1
来源
1.
https://www.cnblogs.com/blackworld-sp/articles/18136480

React Native作为一款流行的跨平台开发框架,其内部原理一直是开发者关注的重点。本文将深入解析React Native的工作机制,从旧框架到新框架的优化,帮助开发者更好地理解和使用这个强大的工具。

React Native基础原理

旧框架

在React Native中我们编写的页面是运行在WebView中,页面的部分功能需要通过Native支持时通过JSBridge进行双向通信,获取Native的功能。

WebView

首先了解下webView,webView是移动端提供的运行JavaScript的环境,是系统渲染Web网页的一个控件,可与页面JavaScript交互,实现混合开发,其中Android和iOS又有些不同:

  • Android的WebView采用的是低版本和高版本使用了不同的webkit内核,4.4后直接使用了Chrome;
  • iOS中UIWebView算是自IOS2就有,但性能较差,特性支持较差,WKWebView是iOS8之后的升级版,性能更强特性支持也较好;
    WebView控件除了能加载指定的url外,还可以对URL请求、JavaScript的对话框、加载进度、页面交互进行强大的处理,之后会提到拦截请求、执行JS脚本都依赖于此;
JSBridge

在Hybrid模式下,H5会经常需要使用Native的功能,比如打开二维码扫描、调用原生页面、获取用户信息等,同时Native也需要向Web端发送推送、更新状态等,而JavaScript是运行在单独的JS Context中(Webview容器、JSCore等),与原生有运行环境的隔离,所以需要有一种机制实现Native端和Web端的双向通信,这就是JSBridge:以JavaScript引擎或Webview容器作为媒介,通过协定协议进行通信,实现Native端和Web端双向通信的一种机制。
通过JSBridge,Web端可以调用Native端的Java接口,同样Native端也可以通过JSBridge调用Web端的JavaScript接口,实现彼此的双向调用

参考:
https://juejin.cn/post/6936814903021797389

RN原理

  1. JavaScriptCore
    JavaScriptCore是一个JS引擎,IOS系统自带了该引擎。Android没有自带,所以React Native会将JSC和app打包在一起,这会增加一点app的体积。另外有一点需要注意,JSC是用户的设备运行js时使用的引擎,但当我们debug时是通过Chrome运行的JS,Chrome通过内置的V8引擎运行JS,通过Websocket和Native的代码进行交互。JSC和V8引擎是不同的js运行环境,所以可能会在Debug时遇到bug,但是在设备上不会出现。

  2. Bridge

  • Shadow Tree
  • JSON(Async) // 公共的中间交互源,很多语言都支持json 用来做数据交互
  • Native Modules 蓝牙 摄像头 网络
    RN Bridge是用
    Java/C++
    编写的,它允许JS线程和Native线程通过一个自定义的通信传输协议来通信。 JS线程会决定什么应该渲染在屏幕上(React组件)。任何用户的UI操作行为都发生在Native线程。比如点击按钮等行为都会序列化后通过bridge发动给JS线程。 此外,Bridge两侧的通信是异步的,一侧发送了消息后,会异步的等待对方侧处理完。
  1. React Native 中主要有 3 个线程
  • JS ThreadJS代码执行线程,负责逻辑层面的处理。Metro(打包工具)将React源码打包成一个单一JS文件(就是图中JSBundle)。然后传给JS引擎执行,现在ios和android统一用的是JSC。
  • UI Thread:Android/iOS(或其它平台)应用中的主线程。这个线程主要负责原生渲染(Native UI)和调用原生能力(Native Modules)比如蓝牙等。
  • Shadow Thread:进行布局计算和构造 UI 界面的线程。创建Shadow Tree, 模拟React结构树,可以类似虚拟dom。RN使用Flexbox布局,但是原生是不支持,所以Yoga就是用来将Flexbox布局转换为原生平台的布局方式。

新框架下

  1. 优化点
  • JS层
  • React:支持 React 16+的新特性,包括async rendering、Data Fetching 等等;
  • 增强JS静态类型检查(CodeGen),来保证消息通信的类型安全,以解决 JavaScript 与 Native 通信中被广为诟病的 Bridge API 数据类型问题
  • 减少数据类型错误
  • 减少数据验证的次数,提高通信性能
  • 引入JSI(JavaScript Interface),允许替换不同的JS引擎
  • Bridge层
  • 划分成Fabic和TurboModules两部分,分别负责UI管理与Native模块
  • Native层
  • 精简核心模块,将非核心部分拆分出去,作为社区模块,独立更新维护

JSI

上层 JavaScript 代码需要一个运行时环境,在 React Native 中这个环境是 JSC(JavaScriptCore)。不同于之前直接将 JavaScript 代码输入给 JSC,新的架构中引入了一层 JSI(JavaScript Interface),作为 JSC 之上的抽象,用来屏蔽 JavaScript 引擎的差异,允许换用不同的 JavaScript 引擎(如最近推出的Hermes)。

更重要的,有了 JSI 之后,JavaScript 还能持有 C++对象的引用,并调用其方法:从而允许JavaScript 与 Native 的直接调用,而不必通过跨线程消息通信,省去序列化/反序列化的成本,还能减轻 Bridge 的通信压力(如大量消息排队堵车);同时JSI 所在的 C++层也可以作为复用 Native 代码的一种方式,拥有 Native 的天然支持:

  • Android:通过 JNI(Java Native Interface)调用 C 或 C++模块;
  • iOS:Objective-C 默认支持;

重构Bridge

新的 Bridge 层被划分成 Fabric 和 TurboModules 两部分:

  • Fabric:负责管理 UI
  • TurboModules:负责与 Native 交互

Fabric
期望以更现代化的方式去实现 React Native 的渲染层,简化之前渲染流程中复杂跨线程交互(React -> Native -> Shadow Tree -> Native UI)。
具体的,直接在 C++层创建 JavaScript 与 Native共享的 Shadow Tree,并通过 JSI 层将 UI 操作接口暴露给 JavaScript,允许 JavaScript 直接控制高优先级的 UI 操作,甚至允许同步调用(应对列表快速滚动、页面切换、手势处理等场景);

TurboModules

  • 实现Native模块按需加载,减少启动时间,提高性能
  • 之前所有 Native Modules(无论是否需要用到)都要在应用启动时进行初始化,因为 Native 不知道 JavaScript 将会调用哪些功能模块。而新的TurboModules 允许按需加载 Native 模块,并在模块初始化之后直接持有其引用,不再依靠消息通信来调用模块功能。因此,应用的启动时间也会有所提升;
  • 通过TSI,可以让JS直接调用Native模块,实现同步操作

总结

  • 线程模型:允许在任意线程中同步调用 JavaScript执行高优先级的更新,UI 更新不再非要跨 3 个线程才能进行;
  • React:支持 React 16+的新特性,包括async rendering、Data Fetching 等等;
  • Bridge:精简优化,允许 Native 与 JavaScript 之间的直接调用;
© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号