揭秘!跨平台方案的历史演进,让你的产品一步登天!

1 跨平台开发背景

对企业来说,移动应用成为各类手机终端上必备的产品名片。

移动互联网开发的应用想取胜,开发效率和使用体验同等重要。但使用原生App要求我们必须针对iOS和Android两平台分别开发,对中小型团队是隐患和额外负担。

因为这样不仅要在不同项目间尝试用不同的语言去实现同样的功能,还要承担由此带来的维护任务。如果还要继续向其他平台(比如Web、Mac或Windows)拓展,要付出成本和时间将成倍增长。这显然难以接受。于是,跨平台开发的概念顺势走进了我们的视野。

所以从本质上, 跨平台开发是为了增加业务代码的复用率,减少因为要适配多个平台带来的工作量,从而降低开发成本。 在提高业务专注度的同时,能够为用户提供一致的用户体验。用一个词来概括这些好处的话,就是“多快好省”。

“一次编码,到处运行”。Java以跨平台口号登场,击败众多对手。意味着Java可在任何平台开发,然后编译成一段标准字节码后,就可以运行在任何安装有JVM的设备。虽然现在跨平台已经不是Java的最大优势(而是它繁荣生态),但不可否认它当年打着跨平台旗号横空出世势不可挡。

而对于移动端开发来讲,如果能实现“一套代码,多端运行”,这样的技术势必会引发新的生产力变革,在目前多终端时代的大环境下,为企业节省人力资源上,从而带来直接经济效益。

伴随着移动端的诞生和繁荣,为了满足人们对开发效率和用户体验的不懈追求,各种跨平台的开发方案也如雨后春笋般涌现。除了React Native和Flutter,这几年还出现过许多其他的解决方案。

跨平台开发方案没有特殊说明的,指跨iOS和Android开发。

2 跨平台开发方案的时代阶段

根据实现方式不同,业内常见的观点是将主流的跨平台方案划分为三个时代。

  • Web容器时代:基于Web相关技术通过浏览器组件来实现界面及功能,典型的框架包括Cordova(PhoneGap)、Ionic和微信小程序。
  • 泛Web容器时代:采用类Web标准进行开发,但在运行时把绘制和渲染交由原生系统接管的技术,代表框架有React Native、Weex和快应用,广义的还包括天猫的Virtual View等。
  • 自绘引擎时代:自带渲染引擎,客户端仅提供一块画布即可获得从业务逻辑到功能呈现的多端高度一致的渲染体验。Flutter,是为数不多的代表。

接下来,我们先看一下目前使用最广泛的Web容器方案。

Web容器时代

Web时代的方案,主要采用的是原生应用内嵌浏览器控件WebView(iOS为UIWebView或WKWebView,Android为WebView)的方式进行HTML5页面渲染,并定义HTML5与原生代码交互协议,将部分原生系统能力暴露给HTML5,从而扩展HTML5的边界。这类交互协议,就是我们通常说的JS Bridge(桥)。

这种开发模式既有原生应用代码又有Web应用代码,因此又被称为Hybrid开发模式。由于HTML5代码只需要开发一次,就能同时在多个系统运行,因此大大降低了开发成本。

由于采用了Web开发技术,社区和资源非常丰富,开发效率也很高。但, 一个完整HTML5页面的展示要经历浏览器控件的加载、解析和渲染三大过程,性能消耗要比原生开发增加N个数量级

接下来,我以加载过程为例,和你说明这个过程的复杂性。

  1. 浏览器控件加载HTML5页面的HTML主文档;
  2. 加载过程中遇到外部CSS文件,浏览器另外发出一个请求,来获取CSS文件;
  3. 遇到图片资源,浏览器也会另外发出一个请求,来获取图片资源。这是异步请求,并不会影响HTML文档的加载。
  4. 加载过程中遇到JavaScript文件,由于JavaScript代码可能会修改DOM树,因此HTML文档会挂起渲染(加载解析渲染同步)的线程,直到JavaScript文件加载解析并执行完毕,才可以恢复HTML文档的渲染线程。
  5. JavaScript代码中有用到CSS文件中的属性样式,于是阻塞,等待CSS加载完毕才能恢复执行。

而这,只是完成HTML5页面渲染的最基础的加载过程。加载、解析和渲染这三个过程在实际运行时又不是完全独立的,还会有交叉。也就是说,会存在一边加载,一边解析,一边渲染的现象。这,就使得页面的展示并不像想象中那么容易。

通过上面的分析你可以看出,一个HTML5页面的展示是多么得复杂!这和原生开发通过简单直接的创建控件,设置属性后即可完成页面渲染有非常大的差异。Web与原生在UI渲染与系统功能调用上各司其职,因此这个时代的框架在Web与原生系统间还有比较明显的、甚至肉眼可见的边界。

图1 Hybrid开发框架

我也曾碰到过很多人觉得跨平台开发不靠谱。但其实,Web容器方案是跨平台开发历史上最成功的例子。也正是因为它太成功了,以至于很多人都忽略了它也是跨平台方案之一。

泛Web容器时代

虽然Web容器方案具有生态繁荣、开发体验友好、生产效率高、跨平台兼容性强等优势,但它最大的问题在于承载着大量Web标准的Web容器过于笨重,以至于性能和体验都达不到与原生同样的水准,在复杂交互和动画上较难实现出优良的用户体验。

而在实际的产品功能研发中,我们通常只会用到Web标准中很小的一部分。面对这样的现实,我们很快就想到:能否对笨重的Web容器进行功能裁剪,在仅保留必要的Web标准和渲染能力的基础上,使得友好的开发体验与稳定的渲染性能保持一个平衡?可以。

泛Web容器时代的解决方案优化了Web容器时代的加载、解析和渲染这三大过程,把影响它们独立运行的Web标准进行了裁剪,以相对简单的方式支持了构建移动端页面必要的Web标准(如Flexbox等),也保证了便捷的前端开发体验;同时,这个时代的解决方案基本上完全放弃了浏览器控件渲染,而是采用原生自带的UI组件实现代替了核心的渲染引擎,仅保持必要的基本控件渲染能力,从而使得渲染过程更加简化,也保证了良好的渲染性能。

也就是说,在泛Web容器时代,我们仍然采用前端友好的JavaScript进行开发,整体加载、渲染机制大大简化,并且由原生接管绘制,即将原生系统作为渲染的后端,为依托于JavaScript虚拟机的JavaScript代码提供所需要的UI控件的实体。这,也是现在绝大部分跨平台框架的思路,而React Native和Weex就是其中的佼佼者。

图2 泛Web容器框架

为了追求性能体验的极致,并进一步维持方案的简单可扩展性,有些轻量级的跨平台方案甚至会完全抛弃Web标准、放弃JavaScript的动态执行能力而自创一套原生DSL,如天猫的 VirtualView 框架。从广义上来说,这些方案也是泛Web容器类方案。

自绘引擎时代

泛Web容器时代使用原生控件承载界面渲染,固然解决了不少性能问题,但同时也带来了新的问题。抛开框架本身需要处理大量平台相关的逻辑外,随着系统版本变化和API的变化,我们还需要处理不同平台的原生控件渲染能力差异,修复各类奇奇怪怪的Bug。始终需要Follow Native的思维方式,就使得泛Web容器框架的跨平台特性被大打折扣。

而这一时期的代表Flutter则开辟了一种全新的思路,即从头到尾重写一套跨平台的UI框架,包括渲染逻辑,甚至是开发语言。

  • 渲染引擎依靠跨平台的Skia图形库来实现,Skia引擎会将使用Dart构建的抽象的视图结构数据加工成GPU数据,交由OpenGL最终提供给GPU渲染,至此完成渲染闭环,因此可以在最大程度上保证一款应用在不同平台、不同设备上的体验一致性
  • 开发语言选用同时支持JIT(Just-in-Time,即时编译)和AOT(Ahead-of-Time,预编译)的Dart,不仅保证开发效率,更提升执行效率(比使用JS开发的泛Web容器方案高得多)

图3 自绘引擎开发框架

通过这样的思路,Flutter可以尽可能地减少不同平台之间的差异, 同时保持和原生开发一样的高性能。所以说,Flutter成了三类跨平台移动开发方案中最灵活的那个,也成了目前最受业界关注的框架。

现在,我们已经弄明白了三类跨平台方案,那么我在开发应用的时候,到底应该如何选择最适合自己的框架呢?

我该选择哪一类跨平台开发方案?

从不同的角度来看,三个时代的跨平台框架代表们在开发效率、渲染性能、维护成本和社区生态上各有优劣,如下图所示:

图 4 主流跨平台框架对比

我们在做技术选型时,可以参考以上维度,从开发效率、技术栈、性能表现、维护成本和社区生态来进行综合考虑。比如,是否必须支持动态化?是只解决Android、iOS的跨端问题,还是要包括Web?对性能要求如何?对多端体验的绝对一致性和维护成本是否有强诉求?

从各个维度综合考量,React Native和Flutter无疑是最均衡的两种跨平台开发方案,而其他的方案或多或少都“偏科严重”。

  • React Native依托于Facebook,经过4年多的发展已经成长为跨平台开发方案的实际领导者,并拥有较为丰富的第三方库和开发社区;
  • Flutter以挑战者姿态出现在我们的面前,可以提供更彻底的跨平台技术解决方案。虽然Flutter推出时间不长,但也有了诸多商用案例,加上清晰的 产品路线图 和Google的强大号召力,Flutter未来的发展非常值得期待。

那么问题来了,我究竟应该选择React Native还是Flutter呢?

建议

知识学习

这两个应用层面的框架最好都学。学习的过程中最重要的是打好基础,深入理解框架的原理和设计思想,重点思考它们的API设计的取舍,发现它们的共性和差异。

Flutter作为后来者,也从React Native社区学习和借鉴了不少的优秀设计,很多概念两边都有对应,比如React Native的Component和Flutter的Widget、Flex布局思想、状态管理和函数式编程等等,这类的知识都是两个框架通用的技术。 未来也许还会出现新的解决方案,老框架也会不断更新,只有掌握核心原理才能真正立于不败之地。

实际项目

这两个框架都已达到了大面积商业应用的标准。综合成熟度和生态,目前看React Native略胜Flutter。因此,中短期项目建议React Native。但技术选型要看得更远。Flutter设计理念较先进,解决方案相对彻底,在渲染能力的一致性以及性能上,和React Native相比优势明显。

Flutter野心不仅移动端。Google团队已完成Hummingbird,即Flutter Web官方Demo,在桌面操作系统探索也取得进展,未来大前端技术栈是否会由Flutter完成统一,值得期待。

总结

不同平台开发和维护同一个产品,所付出的成本一直以来一个令人头疼的问题,于是各类跨平台开发方案顺应而生。从Web容器时代到以React Native、Weex为代表的泛Web容器时代,最后再到以Flutter为代表的自绘引擎时代,这些优秀的跨平台开发框架们慢慢抹平了各个平台的差异,使得操作系统的边界变得越来越模糊。

这时代对开发者要求达新阶段,拥抱大前端已向我们走来。

阅读前提

View是什么,路由是什么,如何实现一个基本页面布局等。

全部评论
good哦
1 回复 分享
发布于 2023-06-27 14:25 北京

相关推荐

点赞 评论 收藏
分享
孤寡孤寡的牛牛很热情:为什么我2本9硕投了很多,都是简历或者挂,难道那个恶心人的测评真的得认真做吗
点赞 评论 收藏
分享
5 6 评论
分享
牛客网
牛客企业服务