主流的跨端方案:
将 JavaScriptCore 引擎当作虚拟机的方案,代表框架:ReactNative
使用非 JavaScriptCore 虚拟机的方案,代表框架:Flutter
跨端方案
编程语言
JavaScript 的历史和流行程度都远超 Dart,生态也更加完善,开发者也远多于 Dart 程序员。虽然两者的入门都相对简单,但从框架和自动化工具的角度来看,ReactNative 也领先 Flutter。这主要得益于 web 技术这么多年的积累,其工具链非常完善,前端开发者可以非常轻松地掌握 ReactNative
性能
ReactNative 与 Flutter 相比,Flutter 的优势最主要体现在性能、开发效率和体验上
- Flutter 采用 Dart 语言编写,同时支持 AOT 和 JIT 两种编译方式,而没有采用 HTML/CSS/JavaScript 方式开发,在b编译执行效率明显高于 JavaScriptCore
- Flutter 的优势还体现在 UI 框架的实现上。重写了 UI 框架,依赖 Skia 图形库和系统图形绘制相关的接口,保证了不同平台上能有相同的体验
原生
原生应用程序是指某一移动平台所特有的应用,使用相应平台支持的开发工具和语言,并直接调用系统提供的 SDK API
比如 iOS 原生应用就是通过 Objective-C 或 Swift 直接调用 iOS SDK 开发的应用程序;而 Android 原生应用就是指使用 Java 或 Kotlin 直接调用 Android SDK 开发的应用程序
主要优势
- 可访问平台全部硬件功能(GPS、摄像头)
- 速度快、性能高,整体用户体验好
缺点
- 平台特定,开发成本高;不同平台必须维护不同代码,人力成本随之变大
- 内容固定,动态化弱,在大多数场景下,只能通过发布新版本来进行迭代
现状
随着移动互联网的高速发展,业务场景越来越复杂,传统的原生开发已经无法满足日益增长的业务需求。
- 动态化内容的增加:当需求发生变化时,原生应用需要通过版本升级来更新内容,但应用上架审核都是需要周期的,这对于高速变化的移动互联网来说是很难接受的
- 业务需求变化快,开发成本变大:原生开发在进行版本迭代时,无论人力成本,还是测试成本都会变大
混合方案:原生+H5
- 微信小程序
- Ionic
这种方案主要原理就是将APP的一部分需要动态变动的内容通过H5来实现,通过原生的网页加载控件Webview来加载。
H5部分是可以随时改变而不用发版,动态化需求能满足;由于 H5 代码值需要一次开发,就能同时在 Android 和 iOS 两个平台运行,这也可以减少开发成本,即 H5 部分功能越多,开发成本就越小。
这种H5+原生的开发模式为混合开发,采用混合模式开发的APP也称为混合应用或Hybrid APP。
主要优点
动态内容是 H5,web技术栈,社区及资源丰富
主要缺点
性能不好,对于复杂用户界面或动画,Webview不堪重负
混合方案:原生+JavaScript
- React Native facebook出品
- Weex 阿里巴巴出品
主要优点
- 采用 Web 开发技术栈,社区庞大、上手快、开发成本相对较低
- 原生渲染,性能相比 H5 提高很多
- 动态化较好,支持热更新
主要缺点
- 渲染时,需要 JavaScript 和原生之间通行,在有些场景,例如:手势拖动可能会因为通行频繁导致卡顿
- JavaScript 为脚本语言,执行时需要 JIT,执行效率和 AOT 代码仍有差距
- 由于渲染依赖原生空间,不同平台的空间需要单独维护,并且当系统更新时,社区控件可能会滞后;除此之外,其他控件系统也会受到原生UI系统限制,例如:在Android中,手势冲突消歧规则是固定的,这在使用不同人写的控件嵌套时,手势冲突问题将会变得非常棘手
React Native
React Native (简称RN)是 Facebook 于2015年4月开源的跨平台移动应用开发框架,是 Facebook 早先开源的 JS 框架 React 在原生移动应用平台的衍生产物,目前支持iOS和Android两个平台。
RN 使用 Javascript 语言,类似于 HTML 的 JSX,以及 CSS 来开发移动应用,因此熟悉 Web前端开发的技术人员只需很少的学习就可以进入移动应用开发领域。
React Native 是 React 在原生移动应用平台的衍生产物。所以 RN 和 React 原理相通,并且 Flutter 也是受 React 启发,很多思想也都是相通的,因此,我们有必要深入了解一下 React 原理。
React是一个响应式的Web框架,我们先了解一下两个重要的概念:DOM 树与响应式编程。
React 和 RN 最主要的区别在于虚拟 DOM 映射的对象是什么?
- React 中虚拟 DOM 最终会映射为浏览器 DOM 树
- RN 中虚拟 DOM 会通过 JavaScriptCore 映射为原生控件树
JavaScriptCore 是一个 JavaScript 解释器,它在 React Native 中主要有两个作用:
- 为 JavaScript 提供运行环境
- 是 JavaScript 与原生应用之间通信的桥梁,和 JSBridge 一样,在 iOS 中,很多 JSBridge 的实现都是基于 JavaScriptCore
RN 中将虚拟 DOM 映射为原生控件的过程中分两步:
- 布局消息传递:将虚拟 DOM 布局信息传递给原生
- 原生根据布局信息通过对应的原生控件渲染控件树
React Native相对于混合应用来说,由于是原生控件渲染,性能会比混合应用中 H5 好很多,同时也是 web 开发技术栈,也只需维护一份代码,同样是跨平台框架
Weex
Weex是阿里巴巴于2016年发布的跨平台移动端开发框架,思想及原理和React Native类似,最大的不同是语法层面,Weex支持Vue语法和Rax语法,Rax 的 DSL(Domain Specific Language) 语法是基于 React JSX 语法而创造。
与 React 不同,在 Rax 中 JSX 是必选的,它不支持通过其它方式创建组件,所以学习 JSX 是使用 Rax 的必要基础。
而React Native只支持JSX语法。
混合方案:原生+自绘
- Flutter 谷歌出品
这种技术的思路是通过不同平台实现一个统一接口的渲染引擎来绘制 UI,而不依赖系统原生控件,所以可以做到不同平台 UI 的一致性
自绘引擎解决的是 UI 的跨平台问题,如果涉及其他系统能力调用,依然需要涉及原生开发
主要优点
性能高,由于自绘引擎是直接调用系统 API 来绘制 UI,所以性能和原生控件很接近
灵活、组件库易维护、UI 外观保真度和一致性高。
由于 UI 渲染不依赖原生控件,也就不需要根据不同平台的控件单独维护一套组件库,所以代码容易维护。
由于组件库是同一套代码,同一个渲染引擎,所以在不同平台,组件显示外观可以做到高保真和高一致性。
由于不依赖原生控件,也就不会受到原生布局系统的限制,这样布局系统会非常灵活。
主要缺点
动态性不足
为了保证 UI 绘制性能,自绘 UI 系统一般会采用 AOT 模式编译其发布包,所以应用发布后,不能像 Hybrid 和 RN 那些使用 JavaScript(JIT)作为开发语言的框架那要动态下发代码
Flutter
Flutter是Google发布的一个用于创建跨平台、高性能移动应用的框架。没有依赖原生控件,而是通过依赖 Skia 图形库和系统图形绘制相关的接口实现了一个自绘引擎。
在开发效率上,Flutter 的热重载可帮助开发者快速地进行测试、构建 UI、调试bug。在 iOS 和 Android 模拟器或真机上可以实现毫米级热重载,并且不会丢失状态。
目前,Flutter社区活跃用户正在高速增长,文档、资源也越来越丰富,加上官方正在大力推广,频繁的版本发布,也让我们相信未来的 Flutter 会更好。