React Native跨平台鸿蒙开发高级应用原理:了解 RN 原生渲染
这里多提一点的是,小程序的组件分为原生组件和非原生组件,对于原生组件而言,这就脱离的 Web 渲染方案的范畴,属于原生渲染方案的一部分,所以从这点上看,小程序也可以算得上是 Web 渲染和原生渲染的融合解决方案。原生渲染方案的基本思路是在 UI 层采用前端框架,然后通过 JavaScript 引擎解析 JS 代码,JS 代码通过 Bridge 层调用原生组件和能力,不同于一般 react 应用,它
跨端技术通识
write once, run everywhere。一次编写,四处运行就是跨端的真谛。跨端的基本原理是跨端引擎需要实现一个渲染引擎、实现一个 vm,基于这套架构实现各种组件和 api,跨端容器上层对接一个 ui 框架,再上层的业务代码可以基于容器的 api 实现跨端的渲染和逻辑。跨平台和跨端的区别在于跨平台是指跨操作系统,而跨端则是指跨客户端。
主流跨端方案
Web 渲染
浏览器本就是一个跨端实现方案,因为你只需要输入网址,就能在任何端的浏览器上打开你的网页。那么,如果我们把浏览器嵌入 app 中,再将地址栏等内容隐藏掉,是不是就能将我们的网页嵌入原生 app 了。而这个嵌入 app 的浏览器,我们把它称之为 webview ,所以只要某个端支持 webview ,那么它就能使用这种方案跨端。同时这也是开发成本最小的一种方案。
使用原生 WebView 控件渲染 HTML 页面,并在原生应用中定义可供 H5 页面访问原生部分能力的接口 JSBridge,从而实现 H5 和 Native 双向通信,也使得 H5 的能力向端侧进一步扩展。
Web 渲染方案本质上是依托原生应用的内嵌浏览器控件 WebView 去渲染 H5 页面,因此 h5 App 的渲染流水线和 Web 页面渲染相一致,能力也局限在 WebView 这一沙箱。
Web 渲染方案的性能瓶颈和 Web 页面开发中遇到的类似,即首屏渲染优化问题(白屏),同时多出了一个 WebView 初始化问题。
针对资源加载所带来的白屏问题,业界又提出了离线包的优化方案。所谓离线包机制,大体思路就是将原有从线上加载 H5 应用,提前下发到本地,通过 FileIO 或是内存等方式直接进行页面渲染,达到接近原生的用户体验。
对于 WebView 初始化所带来的性能开销,不少公司针对自身的 APP 进行内核的定制化改造,诸如腾讯的 X5 内核以及阿里 UC 技术团队的 UCWebView 等。
在这基础上业内又提出 H5 容器的技术解决方案,H5 容器提供丰富的内置 JSAPI,增强版的 WebView 控件以及插件机制等能力,对原始版本的方案做了进一步功能高内聚和模块低耦合。
原生渲染
典型的代表是 React Native 和 Weex。
Web 渲染方案的致命弱点在于无法出色地完成高性能和体验的目标,但是其良好的社区生态、跨平台一致性和高研发效率都是其无法忽视的优势,那么如何做到二者的平衡,答案就是原生渲染方案。
原生渲染方案的基本思路是在 UI 层采用前端框架,然后通过 JavaScript 引擎解析 JS 代码,JS 代码通过 Bridge 层调用原生组件和能力,不同于一般 react 应用,它需要借助原生的能力来进行渲染,组件最终都会被渲染为原生组件,这可以给用户带来比较好的体验。
自渲染引擎渲染
典型代表就是 flutter。自渲染引擎渲染有别于 Web 渲染采用 WebView 容器进行渲染 UI、原生渲染通过 Bridge 方式转化为原生控件渲染 UI 等方案。它并没有直接借用原生能力去渲染组件,而是利用了更底层的渲染能力,直接从底层渲染上实现 UI 的绘制。这种方式显然链路会比上述方案的链路跟短,那么性能也就会更好,同时在保证多端渲染一致性上也会比上一种方案更加可靠 。
小程序另类跨端
小程序采用的技术手段仍脱离不了 Web 渲染方案,即采用 WebView 作为渲染引擎、JSBridge 的封装和离线包机制等,但是其最大创新之处在于将渲染层和逻辑层进行了分离,提供一个干净纯粹的 JavaScript 运行时,多 WebView 的架构使得用户体验进一步逼近原生体验。
小程序的渲染层和逻辑层分别由两个线程管理,渲染层采用 WebView 进行页面渲染(iOS 使用 UIWebView/WKWebView,Android 使用 WebView),小程序的多页面也由多 WebView 接管。逻辑层从 WebView 分离,使用 JavaScript 引擎(iOS 使用 JavaScriptCore,Android 使用 V8)单独开启一个 Worker 线程去执行 JavaScript 代码。逻辑层和渲染层之间的通信经由 Native 层中转,网络 IO 也通过 Native 层进行转发。
和之前的 Web 渲染技术相比较来看,小程序采用多 WebView + 双线程模型的架构。由多 WebView 构成的视图层为页面性能赋予更加接近原生的用户体验,单个 WebView 承载更加轻量的页面渲染任务,JavaScript 脚本单独抽离在 Worker 线程限制了开发者直接操作页面的能力,进一步约束在微信小程序的规范下,这也是小程序无法直接操作 DOM 的缘由。
这里多提一点的是,小程序的组件分为原生组件和非原生组件,对于原生组件而言,这就脱离的 Web 渲染方案的范畴,属于原生渲染方案的一部分,所以从这点上看,小程序也可以算得上是 Web 渲染和原生渲染的融合解决方案。综上来看,Web 渲染跨平台方案经历了三个阶段性的发展,从原始时期的 h5 + JSBridge + WebView,到 h5 容器的抽象提升,再到目前如火如荼的小程序。不难看出,Web 渲染方案的有如下特点:
开发效率高。采用 Web 技术,技术门槛相对较低,技术人员积累丰厚,社区资源丰富,对前端友好,一次开发,多端运行
动态化好。Web 技术的天然动态特性支持,无需发版
表现一致性佳。Web 页面除了个别元素和属性的差异、多屏适配外,其双端表现相对一致
性能较差。页面采用 WebView 渲染,页面加载耗时长,功能受限于沙箱,能力有限,难以承接复杂交互或是需要高性能的任务,整体用户体验差
现在许多大厂都有一套自己的小程序实现,但相互之间还是有不小差异的,通常可以借助 taro ,uni-app,remax 这类框架实现一套代码,多端运行的效果,这也算是一种另类的跨端。
React Native 的整体架构图如下:

- React 层:利用 React 框架进行 UI 的数据描述,开发者使用 Class Component 或 Function Component 进行页面开发,框架内部将会把页面描述转化为 ReactElement 这一代表的虚拟 DOM 的数据结构,用于运行时的 Diff 对比和消息收发等。
- JS Bundle 中间产物:React Native 通过 metro 打包功能直接将整个 RN 应用打包为一个 JSBundle,通过 Bridge 层在 RN 应用初始化时加载整个 JS 包进来
- Bridge 层:Bridge 是连接 React 和 Native 的中间层,React 层的 UI 需要通过 Bridge 层的 UIManager 接口实现原生控件的创建和更新,通过 NativeModules 接口实现原生能力的调用
- Native 层:在 Native 层中,Native Modules 实现了与上层交互的原生能力接口,Native UI 实现终端实际的控件展示,Yoga 跨平台布局引擎实现了基于 Flexbox 布局系统的 JS 和 Native 的镜像映射关系。
值得注意的是,整个 RN 架构中,存在以下 UI 视图数据结构:

RN 运行机制
下面从线程模型角度,分析一下 RN 的运行机制:

更多推荐


所有评论(0)