移动应用跨平台开发的现状及应用

世界已经进入移动的时代。对于任何组织来说,不管组织大小,移动应用都已经成为一项“必备”的元素。“Write once, run anywhere”,人们对跨平台开发的尝试从来没有停止过。特别在这个终端碎片化的时代,一份代码可以在同一个平台不同的系统版本,甚至在不同的平台上运行,对开发者的吸引力越来越大。

一、跨平台开发的现状

跨平台一直是老生常谈的话题,为什么我们需要跨平台开发? 本质上,跨平台开发是为了增加代码复用,减少开发者对多个平台差异适配的工作量,降低开发成本,提高业务专注的同时,提供比Web 更好的体验。通俗了说就是:省钱、偷懒。

HTML5 与 Native 开发的斗争已经持续快十年了,HTML5 性能越来越好,Facebook 的 React Native、阿里的 Weex 等跨平台方案在越来越多的公司中实践,微信小程序更是给了原生开发最沉重的一击,许多小公司可能不再需要开发自己的应用。

那它们的现状是怎样的呢? React Native 和 Weex 方案有哪些优势,又存在什么问题?小程序是不是真的可以一统江湖?而今年火热的 Flutter 技术又会占据什么样的地位呢?从现在看来,前端开发和 Native 开发并没有谁取代谁,而是正在融合,融合之后的产物就是所谓的 “大前端”。

1.1 Web

从桌面时代开始,以浏览器为载体的 Web 技术就具备跨平台、动态更新、扩展性强等优点。随着移动设备性能的增强,Web 页面的性能也逐渐变得可以接受。客户端中出现越来越多的内嵌 Web 页面,很多应用也会把一些功能模块改为 Web 实现。

浏览器内核

一个 Web 页面是由 HTML + CSS + JavaScript 组成,通过浏览器内核执行并渲染成开发者预期的界面。浏览器内核主要包括两大块功能,它们分别是:

  • 浏览器引擎。浏览器引擎负责处理 HTML 和 CSS,遵照的是 W3C 标准。
  • JavaScript 引擎。JS 引擎负责处理 JS,遵照的是 ECMAScript 标准。

它们两者互相独立但又有非常紧密的结合,而且在不同浏览器内核中的实现也是不太一样的。但随着微软的 Edge 宣布将内核切换成 Chromium,目前这个战场主要就剩下苹果和 Google 两个玩家,它们的浏览器引擎分别是 Webkit 和 Blink(其实 Blink 也是 fork 自 Webkit),JS 引擎分别是 JavaScriptCore 和 V8。

对于浏览器的渲染流程,一般来说,HTML、CSS、JS 以及页面用到的一些其他资源(图片、视频、字体等)都需要从网络下载。

性能现状

基于 WebView 的 H5 跨平台方案,优点确实非常明显。但是性能是它目前最大的问题,主要表现在以下两个方面:

  • 启动白屏时间。WebView 是一个非常重量级的控件,无论是 WebView 的初始化,还是整个渲染流程都非常耗时。这导致界面启动的时候会出现一段白屏时间,体验非常糟糕。

  • 响应流畅度。由于单线程、历史包袱等原因,页面的渲染和 JavaScript 的执行效率都不如原生。在一些重交互或者动画复杂的场景,H5 的性能还无法满足诉求。

所以在移动端 H5 主要应用在一些交互不太复杂的场景,一般来说即使帧率不如原生,但也基本符合要求。对于 Android 界面启动的过程,我们在窗口动画还没结束的时候,大部分时候就已经完成了页面的渲染。启动一个 Activity 界面,我们一般要求在 300 毫秒以内。

1.2 React Native & Weex & Flutter

基于 WebView 的 H5 跨平台方案,经过近乎疯狂的性能优化,看起来性能真的不错了。但是对于一些交互和动画复杂的场景(例如左右滑屏、手势),性能还是无法满足要求。

React Native,Facebook 出品,JavaScript 语言,JSCore 引擎,React 设计模式,原生渲染

Facebook 在 2015 年开源了 React Native,它抛弃了 WebView,利用 JavaScriptCore 来做桥接,将 JavaScript 调用转为 Native 调用。也就是说,React Native 最终会生成对应的自定义原生控件,走的是系统原生的渲染流程。

WEEX,Alibaba 出品,JavaScript 语言,JS V8 引擎,Vue 设计模式,原生渲染

而阿里在 2016 年也开源了 Weex,它的思路跟 React Native 很像,但是上层 DSL 使用的是 Vue。对于 Weex 和 React Native 的架构介绍,网上的文章非常多,例如《大前端的下一站何去何从》和《Weex 技术演进》。

Flutter,Google 出品,Dart 语言,Flutter Engine 引擎,响应式设计模式,原生渲染

Flutter 是谷歌2018年发布的跨平台移动UI框架。

但是世上哪有十全十美的方案?React Native/Weex 方案为了能达到接近原生开发的性能和交互体验,必然要在跨平台和动态性上面做出了牺牲。

React Native 和 Weex 向上对接了前端生态,向下对接了原生渲染,看起来是非常完美的方案。但是前端和客户端,客户端中的 Android 和 iOS,它们的差异并不那么容易抹平,强行融合就会遇到各种各样的坑。

“React Native 从入门到放弃”是很多开发者的心声,去年 Airbnb、Udacity 都相继宣布放弃使用 React Native。React Native/Weex 并没有彻底解决跨平台的问题,而且考虑到对外分享和降级容灾的需要,我们依然需要开发一个 H5 版本的页面。

为了解决这个问题,React Native 的使用者需要引入一层非常重的中间层,期望在这个中间层中帮助我们去抹平这些差异。例如京东的 JDReact、携程的 Ctrip React Native。

既然 React Native 和 Weex 在跨平台上面做了牺牲,那它的性能和交互是不是能直接对齐 Native 开发呢?非常遗憾,目前它们的性能我觉得主要还有两个瓶颈。

  • JS 的执行时间。React Native 和 Weex 使用的JavaScriptCore引擎,虽然它每年都在进步,但是 JS 是解释性的动态语言,它的执行效率相比 AOT 编译后的 Java,性能依然会在几倍以上的差距。
  • 跨语言的通信成本。既然要对接前端和原生两个生态,就无法避免 JS -> C++ -> Java/Objective-C 之间频繁的通信和转换,所以这里面会涉及各种序列化,对性能的影响比较大。

虽然相比 H5 方案在性能方面有了很大的提升,但是 React Native 和 Weex 也要面对启动时间慢、帧率不如原生的性能问题。它属于一种比较中庸的方案,当然也会有自己的应用场景。例如一些二级页面(例如淘宝的分会场),它们的业务也比较重要,但是交互不会特别复杂,同时希望保持一定的动态化能力。

当然,Facebook 已经意识到 React Native 的种种性能问题,目前正在疯狂重构中,希望让 React Native 更加轻量化、更适应混合开发,接近甚至达到原生的体验。

1.3 小程序

2017 年初,张小龙宣布微信小程序诞生。如今小程序已经走过了两年,在这两年间,小程序的生态也在健康的发展。

每一个应用都有成为超级 APP 的梦想,各个大厂纷纷推出自己的小程序框架:微信、厂商、支付宝、今日头条、百度、淘宝、Google Play,小程序这个战场已然是“七国大乱战”。

但是小程序并不属于一种跨平台开发方案,大家更看重的是它的渠道优势,考虑如何通过微信、支付宝这些全民 APP 获得更多的流量和用户。从技术上看,小程序的框架技术也是开放的,我们可以采用 H5 方案,也可以采用 React Native 和 Weex,甚至是 Flutter。

从实践上看,我们一起来看看已经正式上线的微信小程序、快应用、支付宝小程序以及百度小程序的差异。

我们可以看到除了独树一帜的快应用,其他小程序的技术方案基本都跟随了微信。但是考虑到 H5 在一些场景的性能问题,利用浏览器内核提供的同层渲染能力,在 WebView 之上支持一些原生的控件。如果哪一天微信小程序支持了所有的原生控件,那也就成为了另外一套 React Native/Weex 方案。

“神仙打架,百姓遭殃”,如果我们想从所有的小程序厂商上面获得流量,那就要开发七个不同的小程序。不过幸运的是,支付宝小程序和快应用也希望已有的微信小程序能快速迁移到自己平台上,所以它们的 DSL 设计都参考了微信的语法,可以说微信推出的 DSL 已然成为了事实标准。

如上图所示,我们希望有一套可以整合所有小程序框架的解决方案,一次开发就可以生成不同的小程序。

二、跨平台开发的应用

从移动开发诞生之初,跨平台就已经是大家前赴后继不断追求的目标。

2.1 跨平台开发的场景

Android、iOS、PC,不同的平台人们的操作习惯、喜好都不尽相同。对于大公司来说,完全的跨平台开发可能是一个伪命题,不同的平台应用的 UI 和交互都不太一样。

那对跨平台苦苦追寻了那么多年,希望得什么呢?跨平台主要的应用场景有:

  • 部分业务。某个业务或者页面的跨平台共享,有的时候我们还希望可以做到跨应用。一个公司共用同一套跨平台方案有非常重大的意义,业务可以在不同的应用中尝试。

  • 核心功能。C++ 才是生命力最顽强的跨平台方案,大公司也将越来越多的核心模块往底层迁移,例如网络库、数据上报、加解密、音视频等。

2.2 跨平台开发对比

H5 的跨平台方案只要投入不太高的开发成本,就能开发出性能、功能还不错的应用。但是如果想做到极致优化,很容易发现开发者可控的东西实在比较少,性能和功能都依赖浏览器的支持。

这个时候如果想走得更远,我们不仅需要了解浏览器的内部机制,可能还需要具备定制、修改浏览器内核的能力,这也是阿里、腾讯、头条和百度都要组建内核团队的原因。

原生开发则相反,刚开始要投入很高的开发成本,但是一旦开始有产出之后,开发者能够有更的发挥空间,而 React Native 和 Weex 方案更是希望打造兼顾跨平台、开发成本以及性能的全方位解决方案。

从目前来看,每一种方案都有着自己的使用场景,无论是 React Natve 还是 H5,都无法完全取代 Native 开发。当然这里也有一个例外,那就是如果我们不再开发应用,全面投向小程序。小程序跟原生开发的竞争,更多的是在渠道层面的竞争。

三、总结

不管跨平台如何发展,对开发者来说,唯一不变的就是学习能力。掌握了学习能力和钻研的精神,就能够应对这些趋势变化。无论移动开发未来如何变化,哪怕有一天 AI 真的能够自动写代码,具备应变能力的人也丝毫不会惧怕的。
(对于我司的情况,主要是与外设备打交道的 APP,完全实现跨平台基本上是不可以,但根据需求通过混合开发来实现最优工程)


五份给自定义为跨平台学习月,以简介入手,从 Flutter 开始。