0%

移动端跨平台方案浅析

前言

本文不涉及到任何代码,只讲概念层面的,结合本人在这几种技术中(Hybrid App的WebView,Picasso(美团点评内部动态化方案),小程序,Futter)的开发经验,对这几种跨平台技术进行一个浅析。另外我在一段时间里也接触到了原生网页开发(html+js+css),算是有些前端开发经验。

跨平台技术的由来:

传统的纯原生开发已经不能满足日益增长的业务需求。主要表现在如下两个方面:

1)动态化内容需求增大。当需求发生变化时,纯原生应用需要通过版本升级来更新内容,但应用上架、审核是需要周期的,这个周期对高速变化的互联网时代来说是很难接受的,所以,对应用动态化(不发版也可以更新应用内容)的需求就变得迫在眉睫了。

2)业务需求变化快,开发成本变大。由于原生开发一般都要维护 Android、iOS两个。

本质上跨平台开发是为了增加代码复用,减少开发者对多个平台适配的工作量,降低开发成本,提高业务专注的同时,提供比 web 更好的体验

常见的移动端跨平台方案

Webview

Webview的主要原理是将APP需要动态变动的一部分内容通过H5来实现,通过原生的网页加载控件 Webview( Android)或 WK Webview(iOS)来加载。这样,H5部分就可以随时改变而不用发版,动态化需求得到满足;同时,由于H5代码只需要一次开发,就能同时在 Android和OS两个平台上正常运行,这也可以降低开发成本,也就是说,H5部分的功能越多,开发成本就越小。我们称这种H5+原生的开发模式为混合开发,对于采用混合模式开发的APP,我们称之为混合应用或 Hybrid APP。

html在移动时代到来以后已经有了很多移动端的适配技术,比如Bootstrap,媒体查询等。所以在一些App弹出的广告页面经常是用html写的。

小程序

包含了RN,Weex,MTRN,Picasso,UniApp,快应用,这些大同小异。核心都是受益于Jscore强大的渲染能力。目前来看小程序是最成功的,其他的在公司中都有应用,但一般都在公司内部用,而且成熟的公司不止一套跨平台js方案。

拿小程序来举例

小程序开发本质上还是前端 HTML + CSS + JS 那一套逻辑,它基于 WebView 和微信自己定义的一套 JS/WXML/WXSS/JSON 来开发和渲染页面。微信官方文档里提到,小程序运行在三端:iOS、Android 和用于调试的开发者工具,三端的脚本执行环境以及用于渲染非原生组件的环境是各不相同的:

  1. 在 iOS 上,小程序的 JavaScript 代码是运行在 JavaScriptCore 中,是由 WKWebView 来渲染的,环境有 iOS 8+;
  2. 在 Android 上,小程序的 JavaScript 代码是通过 X5 JSCore 来解析,是由 X5 基于 Mobile Chrome 53/57 内核来渲染的;
  3. 在 开发工具上, 小程序的 JavaScript 代码是运行在 nwjs 中,是由 Chrome Webview 来渲染的。

Flutter

Flutter与用于构建移动应用程序的其他大多数框架不同,因为 Flutter既不使用Webview,也不使用操作系统的原生控件。相反, Flutter使用自己的高性能渲染引擎来绘制 Widget。这样不仅可以保证在 Android和iOS上UI的一致性,而且可以避免因对原生控件依赖而带来的限制及高昂的维护成本。

Flutter使用ska作为其2D渲染引擎,Skia是 Google的一个2D图形处理函数库,包含字形、坐标转换,以及点阵图,且都有高效能且简洁的表现,Skia是跨平台的,并且其还提供了非常友好的API,目前 Google Chrome浏览器和 Android均采用Skia作为其绘图引擎。目前, Flutter默认支持iOS、 Android、 Fuchsia( Google新的自研操作系统)三个移动平台。但 Flutter亦可支持Web开发( Flutter for Web)和PC开发。

高性能

Flutter的高性能主要靠两点来保证,首先, Flutter APP采用Dart语言开发。 Dart 语言比较特殊,因为它可以通过 AOT(Ahead Of Time) 编译成快速、可预测的本地代码,也可以通过 JIT(Just In Time) 即时编译。开发周期快,工作流颠覆常规(包括 Flutter 流行的秒级有状态热重载)。其次, Flutter使用自己的渲染引擎来绘制UI,布局数据等由Dart语言直接控制,所以在布局过程中不需要像RN那样要在 Javascript和 Native之间通信。

这一点在一些滑动和拖动的场景下具有明显的优势,因为滑动和拖动的过程往往会引起布局发生变化,所以 Javascript需要与 Native不停地同步布局信息,这与在浏览器中要 Javascript频繁操作DOM所带来的问题是相同的,都会带来比较可观的性能开销。

重点:Flutter自己有自己的渲染引擎,这样避免了以上几种跨平台技术的通过中间层通信带来的性能开销,但是依然避免不了写原生代码,因为涉及到平台差异性如相机的调用,权限的调用仍然要写代码来兼容。

对比

比较内容 WebView 小程序等 flutter native
语言 JS 以JS为基础 Dart Android:Java/Kotlin/iOS:OC/Swift
平台实现 JS 引擎解释执行JS代码 JS 引擎解释执行JS代码 开发版本:Dart 虚拟机解释执行 发布版本:Dart 代码编译成目标机器码 Android:安装时编译成目标机器码/iOS:构建时编译成目标机器码
绘制 1、Html+css 2、浏览器引擎绘制 1、JS 生成 DOM 树 2、Native 端解析 DOM 树,转换成原生 View 显示 1、使用 Dart 实现 UI 组件 2、Skia Engine 渲染 原生 View
控件效果 1、样式一致 2、交互效果和原生控件有差距 1、不同平台样式不一致 2、本身就是原生控件 1、样式一致 2、交互效果和原生控件很接近 /
流畅度 一般 较好 和原生相同
动画 一般 和原生相同
动态更新 支持 支持 不支持 不支持
页面开发 整体 APP、模块、单页面 RN:整体 APP、模块、单页面/Weex:单页面 整体 APP、模块、单页面 /
社区支持 丰富 第三方库多,但质量良莠不齐 第三方库较少 丰富
原生UI组件 不能桥接 可以桥接 可以桥接(性能差) /
安装包大小增加 1MB 8MB/10MB 10MB /

总结

移动端的跨平台似乎是大势所趋,但没有一个方案是得到很大的推广,只能根据自身的业务需要去选择合适的方案。在我的开发体验上,Flutter的开发体验比小程序类的好很多,主要是 1.在控件使用上不必去写双端控件适配代码 2.Flutter没有js native通信的代码,在开发效率和性能上较好。在产品开发的快速试错上,flutter开发速度跟小程序差不多,实现功能的能力上比小程序上好,小程序毕竟跳不出微信的框架。

另外,关于我对跨平台方案的看法,如果从使用上来说,每种方案学一学就会用了,做一做ui工程师,如果要深入的话,在工具链以及类似纵向的能力比如webgl或者如weex上有一些深入的理解,这个深入打个比方,weex的深入在于你能理解他的整个渲染机制,比如他的大框架用的是什么,过程中怎么计算布局,怎么做task的调度的,另外,它存在的这些问题,知道不知道是为什么产生,有没有尝试解决和完善这个体系。这个可能是我认为的深度。还是希望能有一专多能的能力,当然如果是好奇心,执行力都很好的情况下,暂时只有广度也是可以的。

参考链接

微信小程序背后运行原理及技术分析 - 简书

第一部分:如何在iOS和Android上选择一个JavaScript 引擎进行应用开发 - 技术翻译 - OSCHINA 社区

王跃:关于微信小程序的技术,也许你想错了-InfoQ

为什么我放弃了 Flutter | AnnatarHe’s blog

uniapp与flutter,跨平台解决方案你该如何选择

移动端跨平台方案