跨平台背景
跨平台解决的问题
纵观跨端技术发展史,想象一根线段,左边是 H5,代表研发效率与动态性;右边是 Native,代表高性能与体验,这几年技术演进的过程,就是通过不断在两个端点间找寻更好平衡的过程,方案无绝对的好坏,而更多是看业务场景诉求,没有银弹,未来这些方案也将在很长一段时间内和平相处,共同构建起大前端的边界与生态。
跨平台分类
按照技术原理,主要可分为如下三类。
- H5(HTML5)+ 原生 ( Cordova、 Ionic、小程序)。
- Javascript 开发 + 原生渲染 ( React Native、Weex、快应用)。
- 自绘渲染(原生、 Flutter)。
跨平台方案汇总
跨平台开发趋势
跨平台技术演进过程
全球跨平台开发技术变化(2019-2020)
主要有以下几点
- React Native仍是目前最普遍的跨平台开发技术。
- Flutter是唯一增长的技术,也是开发者最喜爱的技术。随着2021年发布2.0版本,会有更多的开发者选择Flutter。
- Cordova/Ionic/PhoneGap三个是同一个技术,技术经历了多年,仍是H5+原生开发的最优选择。
19/20 全球移动开发者跨端解决方案使用率,数据来源statista
"Most Popular Technology - Other Frameworks" category in the Stack Overflow Survey 2021.
Other Frameworks and Libraries” category in the Stack Overflow Survey 2021.
三方SDK跨平台支持
常用的三方SDK官方对跨平台的支持情况,三方公司的实际动作,也预示着未来的技术趋势。
Native(Android/iOS) |
H5 |
Flutter |
React Native |
微信小程序 |
支付宝小程序 |
cordova |
uni-app |
其他 |
|
环信 |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
||
友盟 |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
||
极光 |
Y |
Y |
Y |
Y |
Y |
Y |
HBuilder、C、weex |
||
高德地图 |
Y |
Y |
Y |
Y |
Y |
||||
微信支付/分享/登陆 |
Y |
Y |
Y |
||||||
支付宝支付 |
Y |
Y |
Y |
||||||
QQ登陆 |
Y |
Y |
|||||||
阿里云推流 |
Y |
||||||||
阿里云播放器 |
Y |
Y |
Y |
||||||
二维码zxing |
Y |
C++ |
|||||||
bugly |
Y |
||||||||
百度移动统计 |
Y |
Y |
Y |
||||||
mob |
Y |
Y |
Y |
Y |
|||||
总计 |
13 |
8 |
6 |
3 |
5 |
5 |
2 |
3 |
阿里跨平台方向
Native跨平台主流技术
1. H5 Hybrid
这类方案最为直接,简单来说就是用网页来跨端。开发成本低、标准统一、生态繁荣上来说,H5 Hybrid 方案基本是不二之选。
优点:
- 好上手,前端工程师可以直接开发
- 前端成熟度高,生态丰富
APP不直接全用 Web,主要有以下2点原因:
- 性能和体验上差:Web 标准在设计上不是 Design for Performance 的,导致很多地方难以进一步改善,例如 JS 执行和 Layout、渲染互斥无法并行,导致过长的 JS 执行任务会执行正常的渲染导致卡顿。
- W3C 标准作为开放技术标准,历史包袱多,逻辑复杂
案例:Cordova、Ionic :
它们本质上都是使用 HTML、CSS 和 JavaScript 进行跨平台原生应用的开发。该方案说到底是在 iOS 和 Androd 上运行 Web 应用,它在Hybrid基础上优化了 web 跨端时代的两大痛点问题:
- 性能,依靠容器能力,各类离线化、预装包、prefetch 方案大幅减少页面渲染所需加载资源数量,或提前加载时间,配合一些编码上的优化,在 2/3G 及 4G 时代早期把 Web 的秒开体验拉到了与 Native 一个数量级的水平;
- 功能,通过 JSBridge 桥接的方式,规避了 Web 标准制定长流程,及与 Native 原生的割裂带来的底层能力缺失。
但也存在Hybrid已有的问题,比如:
- JavaScript Context 和原生通信频繁,导致性能体验较差;
- 页面逻辑由前端负责,组件也是前端渲染,也造成了性能短板;
- 运行 JavaScript 的 WebView 内核在各平台上不统一;
- 国内厂商对于系统的深度定制,导致内核碎片化。
适用场景
Hybrid&WebView虽然很难满足部分场景对于性能和体验的极致要求,但是会是最稳定、长期存在且得到支持的方案。从开发效率和未来长期的维护演变来看,在能够满足性能体验要求的前提下,Web 方案仍然是最优先应该考虑的。同时,在 APP 的 WebView 容器上我们能做更多的工作,例如通过容器来提供一些端内的能力,结合 Native 能力实现的并行数据加载,页面保活等等。
2. React Native /Weex 类方案
这种方案主要思想是:开发者依然使用 Web 语言(如 React 框架或其他 DSL),但渲染基本交给原生平台处理。通过 JSC(V8)链接 Web 生态与原生控件,结合 React/Vue 等框架,尝试在研发效率与性能体验间寻找更佳的平衡点,也为前端与无线的协同模式开辟了一条新的道路。
主要优势:
- React/Vue生态圈整体发展成熟,社区力量大
- 支持动态化
- 比H5方案的运行效率高
它的主要问题:
- 数据通信过程是异步的,通信成本很高,性能达不到Native的效果
- Native 容器化本质上没有消灭一致性问题,而是把问题转移到了容器层解决,瓶颈依然存在;
- 伴随业务需求的复杂化,每个新特性的支持都会带来容器复杂度的升高,进而影响到性能/体验/稳定性,更多的分层也带来了问题排查难度的提升;
3. Flutter
Flutter 要解决的问题和其他方案不同,完全不打算继续在 Web 生态上借力,从设计之初也并没有把 Web 生态考虑进去。相比于 RN 依赖 Native View 渲染,Flutter 则是自绘的组件,直接通过 Skia 绘制到屏幕上。Flutter 具备其他(主流)跨平台方案所不具备的技术优势,它是更底层,真正意义上的跨端,未来前景大好。
优点:
- 性能高,使用自绘渲染引擎,是最接近原生体验的跨平台技术
- 前景好,是Google下一代移动操作系统Fuchsia开发框架
缺点:
- 作为后入场者,生态达到成熟的程度尚需时日
- 学习dart语言有成本
- 官方不支持动态化/混合栈,需要借助三方库实现
三种主流框架对比
对比维度 |
Apache Cordova |
React Native |
Flutter |
背后支持 |
apple |
||
开发语言 |
使用标准的html语言开发(HTML5, JavaScript and CSS3.),运行在特定平台的native wrappers上。 |
采用JS语言开发,基于React |
Dart语言开发,Flutter runs in the Dart virtual machine, which features a just-in-time (JIT) execution engine. |
支持平台 |
(依赖web view component的多平台支持) mobile – Android, iOS, Windows Phone; desktop – OS X, and Electron (which can be run on Windows, Linux, and OS X).但也导致跨平台或者跨设备的issue,需要特殊处理 |
Android and iOS |
iOS and Android, web (beta), and desktop (technical preview) |
学习门槛 |
low entry threshold(仅需要html,css,js知识) |
基于React,对前端工程师更友好,学习曲线低 |
“everything is a widget” 的理念与react.js和component-based JS frameworks相似,对于熟悉这类开发工作的程序员有较浅的学习曲线Dart需要重新学习,但是与typescript类似 |
UI design |
支持UI custom design |
RN可以利用原生已有的优秀UIRN控件转换为对应平台原生控件的过程,IOS和Android存在一定的差异 |
UI在IOS和Android基本一致。支持Material, Cupertino or fully custom design.但是Material, Cupertino UI的细节调整,较难实现 |
组件 |
大多数能够找到,少部分需要原生定制开发 |
大多数能够找到,customized widgets需要自己实现,可以使用Dart开发或者在原有widgets上开发 |
|
performance and responsiveness |
heavily loaded interfaces can lead to performance bottlenecks |
有效率问题,RN的渲染机制是基于前端框架的考虑,复杂的UI渲染是需要依赖多个view叠加 |
使用高性能渲染引擎来绘 制 widget,有更好的可控性,native-like performance |
与原生服务通信方式 |
在JavaScriptCore(js虚拟机)基础上,封装各平台的应用层接口,定义了 Javascript 和封装后的接口之间的通信协议。以RN的桥接方式和原生服务通信 |
Flutter在跟系统service通信时,通过 Skia 和各平台的底层图形库对接,同时提供丰富的基于 Skia 的控件,来实现跨平台的开发。 |
|
安装包 |
iOS空项目 3M左右,Android20M左右 |
iOS空项目 30M左右,Android空项目 7M左右 |
|
启动速度 |
与原生相差无几 |
较慢 |
|
是否支持热更新 |
支持 |
不支持 |
|
是否支持混编 |
支持 |
支持 |
小程序跨平台技术
小程序的核心是商业模式,而非技术实现。它不为解决跨端问题而生,是一套为了能让三方也接入进来的一套解决方案。小程序技术面向三方能保障业务体验的底线,但小程序技术架构本身的限制导致业务无法去提升上限,所以会有人觉得小程序体验普遍很差。
程序跨端方案大体分为编译时与运行时两类:
- 编译时方案:比较知名的编译时方案是 Taro,大致的原理可以解释为将 JSX 编译到小程序的 WXML/WXSS/JS 上,而这类框架的实现原理其实并非真的是一个 React 或者类 React 框架,而是把看起来像是 JSX 的模板通过静态编译的方式翻译成小程序自身的模板。这样做的限制非常明显,小程序所采用的 WXML 却是一个表达能力非常受限的模板语言,我们不可能完成从一个通用编程语言到模板语言的编译。而静态编译类框架为了做到这一点,采取的方式就是限制开发者的写法,这一点直接导致了无穷尽的维护成本和严重受损的开发体验。
- 运行时方案:remax通过 React Reconciler可以让运行在小程序容器中的 React 不去直接操作 DOM,而是把操作的数据通过 setData 传递给小程序的 View 层映射到最后的界面上。这种做法相对于小程序原生的渲染方式存在一定的性能损耗。
小程序技术框架对比
如何选择跨平台开发框架
跨平台的各个方案无绝对的好坏,而更多是看业务场景诉求,没有银弹,只有适用性。