跨平台开发的背景
在移动互联网的浪潮下,我们开发的应用要想取胜,开发效率和使用体验可以说是同等重要。但是,使用原生的方式来开发App,就要求我们必须针对iOS和Android这两个平台分别开发,这对于中小型团队来说就是隐患和额外的负担。
因为这样的话,我们不仅需要在不同的项目间尝试用不同的语言去实现同样的功能,还要承担由此带来的维护任务。如果还要继续向其他平台(比如Web、Mac或Windows)拓展的话,我们需要付出的成本和时间将成倍增长。而这,显然是难以接受的。于是,跨平台开发的概念顺势走进了我们的视野。
所以从本质上讲,跨平台开发是为了增加业务代码的复用率,减少因为要适配多个平台带来的工作量,从而降低开发成本。 在提高业务专注度的同时,能够为用户提供一致的用户体验。用一个词来概括这些好处的话,就是“多快好省”。
“一次编码,到处运行”。二十多年前Java正是以跨平台特性的口号登场,击败了众多竞争对手。这个口号,意味着Java可以在任何平台上进行开发,然后编译成一段标准的字节码后,就可以运行在任何安装有Java虚拟机(JVM)的设备上。虽然现在跨平台已经不是Java的最大优势(而是它繁荣的生态),但不可否认它当年打着跨平台旗号横空出世时确实势不可挡。
伴随着移动端的诞生和繁荣,为了满足人们对开发效率和用户体验的不懈追求,各种跨平台的开发方案也如雨后春笋般涌现。除了React Native和Flutter之外,还出现过许多其他的解决方案
跨平台开发方案的不同时代
1. Web App 时代(H5混合开发)
代表技术:HTML5、CSS3、JavaScript、Hybrid App(如Cordova/PhoneGap)特点:
- 通过Web技术开发应用,运行在WebView中
- 一套代码多端运行,开发效率高
- 访问部分原生能力需依赖插件
- 用户体验和性能有限,界面与原生有差距
典型案例:早期的微信H5页面、Cordova/PhoneGap应用
2. 混合开发(Hybrid App)时代
代表技术:React Native、Weex、原生+WebView混合架构特点:
- 采用“原生+Web”混合架构,核心页面用Web技术,关键页面用原生开发
- React Native/Weex等方案允许用JavaScript等语言调用原生组件,提升性能和体验
- 代码复用率提升,部分场景接近原生体验
- 仍需维护原生和Web两套代码,复杂度较高
典型案例:美团、阿里等大型App的Hybrid架构
Web时代的方案,主要采用的是原生应用内嵌浏览器控件WebView(iOS为UIWebView或WKWebView,Android为WebView)的方式进行HTML5页面渲染,并定义HTML5与原生代码交互协议,将部分原生系统能力暴露给HTML5,从而扩展HTML5的边界。这类交互协议,就是我们通常说的JS Bridge(桥)。
这种开发模式既有原生应用代码又有Web应用代码,因此又被称为Hybrid开发模式。由于HTML5代码只需要开发一次,就能同时在多个系统运行,因此大大降低了开发成本。
由于采用了Web开发技术,社区和资源非常丰富,开发效率也很高。但,一个完整HTML5页面的展示要经历浏览器控件的加载、解析和渲染三大过程,性能消耗要比原生开发增加N个数量级。
以加载过程为例,说明这个过程的复杂性。
- 浏览器控件加载HTML5页面的HTML主文档;
- 加载过程中遇到外部CSS文件,浏览器另外发出一个请求,来获取CSS文件;
- 遇到图片资源,浏览器也会另外发出一个请求,来获取图片资源。这是异步请求,并不会影响HTML文档的加载。
- 加载过程中遇到JavaScript文件,由于JavaScript代码可能会修改DOM树,因此HTML文档会挂起渲染(加载解析渲染同步)的线程,直到JavaScript文件加载解析并执行完毕,才可以恢复HTML文档的渲染线程。
- JavaScript代码中有用到CSS文件中的属性样式,于是阻塞,等待CSS加载完毕才能恢复执行。
而这,只是完成HTML5页面渲染的最基础的加载过程。加载、解析和渲染这三个过程在实际运行时又不是完全独立的,还会有交叉。也就是说,会存在一边加载,一边解析,一边渲染的现象。这,就使得页面的展示并不像想象中那么容易。
通过上面的分析可以看出,一个HTML5页面的展示是多么得复杂!这和原生开发通过简单直接的创建控件,设置属性后即可完成页面渲染有非常大的差异。Web与原生在UI渲染与系统功能调用上各司其职,因此这个时代的框架在Web与原生系统间还有比较明显的、甚至肉眼可见的边界。
虽然Web容器方案具有生态繁荣、开发体验友好、生产效率高、跨平台兼容性强等优势,但它最大的问题在于承载着大量Web标准的Web容器过于笨重,以至于性能和体验都达不到与原生同样的水准,在复杂交互和动画上较难实现出优良的用户体验。
而在实际的产品功能研发中,我们通常只会用到Web标准中很小的一部分。面对这样的现实,我们很快就想到:能否对笨重的Web容器进行功能裁剪,在仅保留必要的Web标准和渲染能力的基础上,使得友好的开发体验与稳定的渲染性能保持一个平衡?
答案当然是可以。
解决方案优化了Web容器的加载、解析和渲染这三大过程,把影响它们独立运行的Web标准进行了裁剪,以相对简单的方式支持了构建移动端页面必要的Web标准(如Flexbox等),也保证了便捷的前端开发体验;同时,基本上完全放弃了浏览器控件渲染,而是采用原生自带的UI组件实现代替了核心的渲染引擎,仅保持必要的基本控件渲染能力,从而使得渲染过程更加简化,也保证了良好的渲染性能。
也就是说,我们仍然采用前端友好的JavaScript进行开发,整体加载、渲染机制大大简化,并且由原生接管绘制,即将原生系统作为渲染的后端,为依托于JavaScript虚拟机的JavaScript代码提供所需要的UI控件的实体。这,也是现在绝大部分跨平台框架的思路,而React Native和Weex就是其中的佼佼者。
为了追求性能体验的极致,并进一步维持方案的简单可扩展性,有些轻量级的跨平台方案甚至会完全抛弃Web标准、放弃JavaScript的动态执行能力而自创一套原生DSL
3. 跨平台原生开发(全平台统一渲染)时代
代表技术:Flutter、Xamarin、Kotlin Multiplatform、UniApp、Taro特点:
- 通过统一的跨平台框架,实现一次开发多端部署
- Flutter等方案自绘UI,性能接近原生
- 支持iOS、Android,甚至Web、桌面等多端
- 生态完善,开发体验和效率大幅提升
典型案例:Flutter应用(如闲鱼)、UniApp/Taro等小程序/多端应用
使用原生控件承载界面渲染,固然解决了不少性能问题,但同时也带来了新的问题。抛开框架本身需要处理大量平台相关的逻辑外,随着系统版本变化和API的变化,还需要处理不同平台的原生控件渲染能力差异,修复各类奇奇怪怪的Bug。始终需要Follow Native的思维方式,就使得框架的跨平台特性被大打折扣。
而这一时期的代表Flutter则开辟了一种全新的思路,即从头到尾重写一套跨平台的UI框架,包括渲染逻辑,甚至是开发语言。
- 渲染引擎依靠跨平台的Skia图形库来实现,Skia引擎会将使用Dart构建的抽象的视图结构数据加工成GPU数据,交由OpenGL最终提供给GPU渲染,至此完成渲染闭环,因此可以在最大程度上保证一款应用在不同平台、不同设备上的体验一致性。
- 而开发语言选用的是同时支持JIT(Just-in-Time,即时编译)和AOT(Ahead-of-Time,预编译)的Dart,不仅保证了开发效率,更提升了执行效率(比使用JavaScript开发的Web容器方案要高得多)。
通过这样的思路,Flutter可以尽可能地减少不同平台之间的差异, 同时保持和原生开发一样的高性能。所以说,Flutter成了三类跨平台移动开发方案中最灵活的那个,也成了目前最受业界关注的框架。
如何选择跨平台开发方案?
在做技术选型时,可以从开发效率、技术栈、性能表现、维护成本和社区生态来进行综合考虑。比如,是否必须支持动态化?是只解决Android、iOS的跨端问题,还是要包括Web?对性能要求如何?对多端体验的绝对一致性和维护成本是否有强诉求?以下是个人建议供参考:
1. 开发效率
- Web/H5方案(如Hybrid、UniApp、Taro等)
- 优点:上手快,前端开发者易于转型,代码复用率高,适合快速迭代。
- 缺点:部分原生能力支持有限,复杂交互实现难度大。
- Flutter/React Native等原生跨平台方案
- 优点:一次开发多端部署,UI一致性好,开发效率高于纯原生。
- 缺点:需要学习新语言/框架(如Dart),部分平台特性需单独适配。
2. 渲染性能
- Web/H5方案
- 优点:适合信息展示类、轻量级应用。
- 缺点:动画、复杂交互、列表等场景性能不及原生,体验有差距。
- Flutter/React Native
- 优点:接近原生性能,适合高性能、高交互需求的应用。
- 缺点:极端性能场景(如大型游戏)仍不如纯原生。
3. 维护成本
- Web/H5方案
- 优点:一套代码多端复用,维护成本低。
- 缺点:多端兼容性问题多,需关注不同平台的适配。
- Flutter/React Native
- 优点:主流平台(iOS/Android)可统一维护,社区有丰富插件。
- 缺点:遇到平台特有需求时,仍需写原生代码,增加维护难度。
4. 社区生态
- Web/H5方案
- 优点:前端生态成熟,组件/库丰富,开发者众多。
- 缺点:部分新平台(如小程序、快应用)生态相对分散。
- Flutter/React Native
- 优点:社区活跃,官方和第三方插件丰富,文档完善。
- 缺点:部分新特性/新平台支持滞后于原生。
选择建议
1. 业务类型
- 信息展示、轻量级应用:优先考虑Web/H5、UniApp、Taro等方案。
- 高性能、复杂交互应用:优先考虑Flutter、React Native等原生跨平台方案。
- 需要接入小程序/快应用生态:选择支持多端适配的框架(如UniApp、Taro)。
2. 团队技术栈
- 前端为主:Web/H5、UniApp、Taro上手快。
- 有原生开发经验:Flutter、React Native更易发挥团队优势。
3. 未来维护和扩展
- 追求长期可维护性:选择社区活跃、文档完善、插件丰富的方案。
- 需频繁适配新平台:优先选用生态完善、适配能力强的框架。
4. 其他考虑
- UI一致性要求高:Flutter自绘UI一致性最好。
- 需要快速上线 MVP:Web/H5方案开发最快。
- 预算有限:跨平台方案整体优于双端原生开发。