
运行机制 React Native 的运行机制基于两个线程之间的通信( Javascript 线程和 Native 线程),通过 Bridge (桥) 实现数据交互。这使得 JS 逻辑与原生界面可以协同工作,实现流畅体验。
优势
哲学与设计理念 React Native 并不是完全跨平台,而是通过处理 Native 重叠部分来实现最大化复用代码。它强调 “Learn once, write anywhere” 而不是 “write once, run anywhere”。
平台选择的考量 文章也提到在选择 React Native 还是原生开发时,需根据产品的实际需求、团队技术栈、性能要求等因素综合考虑。例如:
背景与定义 React Native 是由 Facebook 创建的,基于 Javascript 的跨平台开发框架,旨在帮助开发者使用一套代码同时构建 iOS 和 Android 应用。
Facebook 创建了 React-Native ( RN )来构建 app。它最初是在 2013 年的夏天在 Facebook 内部的一个项目,2015 年成为开源项目,是因为当时 React 在社区的呼声很高,他们就觉得 React 是一个很好的UI 框架,那么如果你想构建一个 native-app,为什么不直接让在 React 跑在移动端的操作系统上那!
因此,在同一年,Facebook 将 React分为两个独立的库,也就是 React和 React-dom,可能大伙对这个概念还挺模糊的,我简单解释一下。
React: React 是一种用于构建用户界面的 Javascript 库。它是一个核心库,用来创建 React 元素 (elements)、组件 (components) 和虚拟 DOM (Virtual DOM),并在应用程序中管理组件的状态和生命周期。React 可以在客户端和服务器端使用也包括了React Native。
React-dom: React-DOM 是 React 库针对浏览器的针对 DOM 操作的补充。React-DOM 提供了与 DOM 相关的功能,比如把 React 组件渲染到 DOM 中,处理用户交互等事件。
简单来说,React 库提供了一个基础构建组件树的库,而 React-DOM 则为你提供了一些针对 Web 页面的工具,如将组件渲染到网页中,并支持通过事件响应来进行交互。
从那时起,React 就不用关心组件的渲染在哪个平台上。Web 平台的渲染由 ReactDOM 承担,而移动平台的渲染由 RN 承担。
RN 是一个基于 Javascript 的跨端框架,RN提供了一套代码多个平台运行的能力。
它最开始解决的问题是,在安卓上,开发者需要实现一套Java app,又在 ios, 需要实现Swift,我们就需要学习两门语言,去实现一个完整的app。
那时候就感觉像是这样的。
web开发者要了解HTML,CSS,JS,React安卓开发者要了解Java,Kotlin SDKios开发者要了解Object-c,Swift,CocoaPods.而在 R 系大家庭中,React-native应运而生,引入一个新的platform去平替上者后 2 。
它现在看起来是这样的
这就是我前面讲到的,React仅仅是管理Fiber 树,em 或者说组件树,而渲染交给了react-dom或者react-native。
我们进一步研究一下,究竟是如何在我们的app上跑的,rn其实是用React、Js去调用native 组件然后构建app。例如,<Image/>组件代表了另外两个本地组件, 安卓的ImageView、iOS 的UIImageView。在这rn的架构中是由两个线程控制的,一个js线程、一个native线程。
js线程的东西,我们先有个概念,举个例子:我们的浏览器用虚拟引擎去执行js代码就像是v8。意思就是我们的代码如果要跑在rn上同样需要一个虚拟引擎,去执行我们的api、处理我们的事件。在最开始就是ios内置的JScore这个引擎,但这个引擎在打包安卓的时候会把包搞大,又用不上,所以就在 0.6 这个版本后采用Hermes这个新引擎,在 0.64 后 ios 也采用这个引擎了,毕竟它确实更好,如下它的优势。内存使用更小。与浏览器中一样,rn中的JS是在单个线程中实现的。该线程负责执行JS。我们正在编写的业务逻辑将在这个线程中执行。
这意味着我们所有的通用代码,如组件、状态、钩子和REST API调用,将在应用程序的 JS 部分中处理。
native线程是做啥那,其实就是执行native代码的地方,rn它在每个平台(java、oc、ios)上都去实现了这一部分,这个线程绝大部分的内容都是与安卓 ios通信的sdk,同时为我们提供统一的api。举个例子:就是比如我调用一个alert弹窗,native层就整合了 2 个平台提供了一个统一的api,然后我们在js线程中去调用他。实际上这是线程的交互,在native线程的角度来看,就我们要弹出个警告,他其实是两个部分,Native ui去更新页面,Native Moudles去访问平台特有的功能。上面我们说了一下两个线程分别是干啥的,紧接着就肯定离不开线程之间的通信,而这两个线程之间的通信是通过桥(就这么理解吧),这个桥是用C++写的,并基于一个异步队列。当桥从其中一方接收数据时,它将其序列化,将其转换为 JSON 字符串,然后把它排在队列中。在到达目的地后,数据就被反序列化。
就以上面的alert为例,native接受来自JS的回调并显示该对话框。实际上,JS方法在被调用时,向桥发送消息,并接收到到消息时,native执行指令。本机消息也可以被转发到JS。例如,单击该按钮时,native向js发送一个单击事件消息。就大概像这样:
大家应该很容易发现问题,就是因为所有的事件都依赖于异步的桥去完成通信,那可能会面临就是说队列负载过高,就导致的性能问题,但确实也存在,只能说有利有弊了,我们先留下这个悬念,后面再看看RN的架构中是如何处理这个问题的(下一篇再讲新架构内容太多了)。
其实RN 使用就是使用异步回调去操作底层的移动端操作系统,也就是调用原生的api。rn有一个Javascript引擎,并且RN API与Web的React基本相同,区别在于原生端;Rn是异步调用的原生 API ,而不是 DOM 。如图所示:
RN 使用与web上使用的相同React库(也就是前面提到的React核心库),并在 JavascriptCore中运行。Native api的消息是异步和批处理的。RN附带了为移动平台实现的组件,而不是 HTML 元素的组件.RN其实代表的是通过iOS和Android api 渲染组件的方法。它可以用同样的概念来在tvOS、电视、Windows 、macOS ,甚至是 Web 上渲染。为React去实现一个新的渲染其实还挺难的,就大伙想象一下这就像发明一个可以运行在ios和Android的新的dom难度,但跨端应用还是不得不做,就我想了一下有这几个原因吧。
rn这种其实算是变相调用原生的api会好很多。jsx,可能我对flutter的好感不如rn的原因就是因为这个吧,学习成本低了。就这里只谈谈自己对RN的感觉。
怎么说那?就是可能大家觉得rn,应该就是你可以用react的语法写一个跑在任何原生设备上的应用。
但不行,因为ios和安卓在许多最基本的层面就是不一样的,甚至它们的UX哲学完全不同(这其实也是 ios 好很多的原因),所以其实想写一个不处理两种情况的单一 app其实还真不行。
简单的说就是,rn不是实现一个组件库让你在任何地方跑,它处理的只是native重叠的地方。rn不是写一次,就可以在任何地方跑(除非你完全不在意用户体验),它应该说是学习一次,写在任务地方。你需要在某些情况,用特定ios/安卓组件,去提供更好的UX(但其实rn已经帮你处理很多差异和提供很多通用基础组件了,只是你可能需要脑子里对平台差异有个类似于红线认知的东西)
对于用户来说,Web 应用的使用门槛远低于 App。如果没有强需求,大家通常并不愿意安装一个久未使用、图标发灰的 App ,而是更倾向于直接打开浏览器获取信息,尽管 Web 的使用体验可能不如 App 那么好。
那么,当我们手头有一个面向 C 端的产品时,应该如何选择平台呢?
从产品规模和功能复杂度的角度来看:
从技术角度来说,移动端浏览器确实缺乏许多移动 App 的能力,主要原因包括以下几点:
浏览器中的 HTML 元素无法与原生组件在交互与视觉体验上保持一致。例如,一些 UI 设计会提出“在移动端展示复杂表格”的需求,但实际上这违背了移动端轻交互的设计理念,体验通常很差。
移动 Web 无法很好地支持原生 App 中的高级功能,如原生手势系统。Web 中的点击事件只是单一的响应,而原生中,用户手指的滑动、长按、按压等都由专门的系统处理,开发者只需关注逻辑即可。而在 Web 中实现这些,需要自己去监听 touch 事件、处理手势的 x/y 坐标、时间等,开发成本高,效果也不稳定。
移动端 Web 在 UI 和交互上难以与原生统一,不适合实现复杂交互,像“移动端上做复杂表格”这类设计在体验上本身就不合理。
Web 应用缺乏原生能力支持,尤其在交互、手势、动画等方面难以还原原生体验。
因此,平台的选择要基于产品复杂度、目标用户习惯、开发成本和迭代速度综合权衡。
欢迎加入群聊,我们一起讨论一些更有趣的技术、商业、闲聊。
因为最近业务在写Rn,就正好巩固一下一些知识,也增强大伙的竞争力,后面估计这个部分会出很多章,想这种概念的东西还挺重要的,大伙可以吸收一下。
1 paranoiagu 166 天前 via Android 自持鸿蒙 next 吗? |
2 murmur 166 天前 |
5 pointup 136 天前 个人建议选择 Flutter 吧或者原生来写 app 。(如果你需要面向国内用户使用的话) |