本文来源:mPaaS
根据公开的 2018 年移动互联网行业分析报告,目前支付宝的月活跃用户已经超过 QQ ,成为国内第二大 App。前端
支付宝一开始仅仅只是一个单体应用的工具型 App,让用户能够在手机完成支付宝相关的业务查询和操做。2013 年后,支付宝逐步转型为平台型 App, 平台型 App 具备服务化、模块化、工具组件化的特色。这个时候支付宝的业务不只仅是支付,还须要给客户提供不少生活相关的服务,例如余额宝、缴电费等。2015 年后支付宝成长为超级 App,此时支付宝里面须要支持大量复杂的业务,同时开放本身的商业能力,用本身流量助力合做伙伴,所以整个 App 面临开放、动态化、高可用的挑战,面对这些挑战,咱们把它总结为如下三点:git
App 的业务愈来愈复杂,不只仅是内部业务,还包含了大量外部的合做伙伴。若是采用传统的 App 开发方式很难应对日趋复杂的业务场景。github
1.1 Hybrid 技术方案选型面试
在 Hybrid 技术方案选型方面,咱们经过“开发成本、用户体验、动态性、复杂业务支持能力、研发难度”五个方面综合考量。咱们筛选出 HTML五、ReactNative/Weex、Flutter 做为备选,并将原生开发做为基准线完成对比。(考虑到近期 Flutter 的热度持续走高,所以咱们归入 Flutter 一并分析。)算法
首先咱们从业务开发成本角度来看:小程序
接下来咱们讨论用户体验:浏览器
接着是动态性的支持:安全
在本文第二章节“离线包机制+发布平台”,咱们会从快速迭代的角度深度分析动态性在支撑高并发业务场景下的重要性。服务器
首先,动态性最优的就是 HTML5 方案:能够访问在线页面,服务端即时生效,也能够经过下发资源的方式,进行动态更新;网络
其次是 ReactNative/Weex 方案,经过必定的定制,开发者能够将前端包热部署、热更新。不过相较于 HTML5 具有的“在线+离线”的动态性,该方案仍然存在必定差距;
接下来是原生,Android/iOS 双端都可以经过一些黑科技手段,进行动态更新,不过因为 iOS 政策禁止,所以在动态性上,原生方案暂时不推荐;
最后是 Flutter,虽然有很强大的热重载机制,不过因为 Google 的限制,线上版本 iOS 没法作到热更新,所以在动态性评估中将 Flutter 排在最后。
最后咱们聊下各个方案的实现起来的研发难度:
综上所述,咱们再考虑了各方的优劣以后,决定采用“HTML5 容器+内核优化”的方式来应对复杂业务的开发问题。接下来咱们就介绍下容器的架构。
1.2 容器架构
最上层是原生的 HTML5 代码,这块就是你们常见的 Web 开发环境,包括 HTML、CSS、JavaScript等。
下面一层即离线包管理,这个咱们在第二章节内进行详细介绍。
再往下是 HTML5 容器层,HTML5 容器做为中间层,将浏览器和支付宝底层框架有机结合起来,同时还提供各类生命周期机制、事件机制、扩展插件等内容。
在 HTML5 容器里面有个很是重要的概念: JSBridge。经过 JSBridge,HTML5 容器将支付宝框架底层以及中间件层提供的各类能力和 HTML5 前端代码进行联通,其中包括 RPC(远程过程调用,用来实现 App 和服务器通讯)、支付、扫一扫等。
最下面是支付宝底层框架,提供微应用,微服务等概念。一个 HTML5 应用,也会被框架模拟成一个微应用,经过应用 ID 进行解耦。
1.2.1 JSBridge 介绍
JSBridge 是 HTML5 容器的基石,桥接了 JS 环境与 Native,实现了 Native 代码和浏览器环境的双向通讯,Native 代码能够经过调用浏览器提供的接口运行JS,从而实现调用 JS 函数、传递参数到 JS 环境等;而浏览器到JS环境的通讯是经过 Native 拦截浏览器的请求来实现,请求能够是网络请求或者是一些内部函数的调用。
1.2.2 H5 容器定制化扩展
HTML5 容器提供了 2 种扩展方式:
JSAPI 方式给 HTML5 页面增长了 Native 功能调用接口,经过实现自定义 JSAPI 类中的 Handler 方式,能够以 Native 的形式实现特定功能,例如调用 Native 加密函数。
HTML5 容器在状态变化时会发送事件,经过监听 HTML5 容器特定事件,能够实现对 HTML5 容器生命周期的处理,好比修改加载进度条颜色、修改页面导航栏等。事件提供了更强的定制性,彻底能够知足对 HTML5 容器的各类自定义需求
1.3 容器稳定性
上面在研发难度中,咱们说起到了,HTML5 方式的研发难度是最高的,由于须要定制化内核进行性能及稳定性优化。目前支付宝采用的是阿里集团的 UC 自研内核,并针对支付宝的 HTML5 容器进行了深度优化和定制。如图所示,UC 内核和系统内核的卡顿卡死率的数据对比效果很是显著,咱们能够直观地看到 Webview 稳定性的提高。
目前支付宝业务的另一个特色就是须要快速迭代,变化的政策、突发事件都须要咱们能够快速把新的业务需求触达给用户。可是对于 App 开发者有一个不容忽视的问题,就是应用商店审核。因为审核的存在,App 上开发的业务会有一个统一排期,好比说月底会有新版本,那么全部的业务进度都得考虑 App 的排期计划。
2.1 离线包机制
为了作到良好的用户体验,咱们在容器中引入了离线包机制。经过离线包机制,咱们将原有从线上加载的 HTML5 应用,提早下发到本地,经过读取 IO,或者是内存,进行页面的渲染,达到接近原生的用户体验。
经过发布平台,咱们能够将不一样的 HTML5 离线包,以单独应用的形式,进行不一样维度的下发,使原来 all in 的 Native 发布模式,改成各业务线自行定制发布计划,自行制定发布标准,自行发布的并行发布形式,来知足业务的快速迭代。
2.1.1 加载机制
经过内存提早加载,定时更新,启动预加载内存等手段,咱们将一个业务包须要用到的资源加载到内存,从而使启动过程尽可能无感知,页面秒开无白屏。同时,咱们还有 Fallback 手段,保证在包损坏或者是未下载完成时,能够经过在线页面的形式,保证业务的 100% 可用性。
2.1.2 公共资源包机制
所谓公共资源包,即全部 HTML5 离线包均可能会用到的公共资源的集合。公共资源包解决多个 HTML5 应用使用同一资源产生的冗余问题。如 React 应用使用 ReactJS 框架代码。您能够将公共资源放入全局资源包,以下降 HTML5 应用体积。
经过公共资源包机制,可有效下降各 HTML5 应用的包体积,从而使更新率提升,页面开启速度加快。
2.2 发布平台
为了知足快速迭代的需求,一个强大的发布平台也是必不可少的。发布平台的核心指标,就是将发布内容高效、精准的投放到指定的设备上,为了实现这个目标,咱们作了以下的努力。
2.2.1 离线包大小管控及差量包机制
HTML5 容器离线包提供了更新机制,以单个离线包做为更新维度。由于单个离线包业务很简单,因此离线包的大小是可控的,一般小于 500KB。咱们经过大量的实践,总结出来“500KB”这个值,既能够知足单个业务的内容,也能够更高效地发布到设备上。500KB,在 4G 的时代,几乎能够作到用户无感知更新,即使是 2G/3G 也能够保证一个高的到达率。
上面说的是一个 HTML5 应用的大小。实际上,咱们更新的包会更小,发布平台会经过 diff 算法,计算出相同 HTML5 应用两个不一样的版本的差量包,差量包一般也就在几 KB 至几十 KB 不等,能够作到更高的下载成功率,下载成功率必定程度就意味着实际到达率。
2.2.2 Fallback 机制
在一些极端网络场景下,新的业务资源包更新失败,而咱们又指望用户使用的是最新的业务,这个时候 Fallback 访问机制就会发挥做用。每一个离线包资源都会在发布服平台上存放一份,在刚刚说到的极端场景下,用户会访问服务器的 Fallback 地址获取资源,从而保障页面可用。
2.2.3 多维发布
另外,针对刚开发好的应用,咱们能够经过发布平台的灰度发布进行发放,经过外部灰度的形式,对业务指标进行验证,达到标准后,方可正式发布,作到可灰度,可回滚。
做为超级 App,一个最主要的特征就是开放。开放就是共享 App 的流量,让外部伙伴的业务能够经过支付宝触达用户,这就面临一个质量管控的问题。支付宝须要保证这些业务是合法合规的,保障用户的财产安全。
3.1 离线包 VS 小程序
若是开发一方业务,离线包确定是很是好的选择。不过,要是开放给第三方合做伙伴构建生态的话,纯 HTML5 页面就有一些劣势。
上图是 HTML5 离线包和小程序的细节对比。总结来讲,对于开放给第三方的生态,从应用体验来说,小程序更加统一,质量有保障;从应用安全角度来说,小程序是访问我方发布服务器,不会直接访问第三方连接,安全可控;从研发门槛上来讲,小程序是更简单的前端开发方式,同时也提供了很是丰富的组件。
3.2 小程序解析
小程序其实和离线包本质是相似的,都是一种 Hybrid 应用,但小程序是基于一个定制的 DSL 语言,不是前端的标准,可是相似。在 DSL 规则下业务进行小程序的开发,不支持直接操做 DOM,这种 DSL 规则下的自由能够有效的进行质量管控。
小程序做为一个应用,他拥有完整的生命周期。从开发到关闭,开发者均可以感觉到,这点也是 HTML5 所不具有的。另外,每一个小程序之间从运行时和持久化上,都是彻底隔离的,并且小程序运行在特定进程中,因此和支付宝也是隔离开的。
在渲染性能上,小程序采用双线程模式将页面渲染和业务逻辑分别放在两个单独的线程中,renderer 运行在 WebView 中,负责渲染界面;小程序业务逻辑运行在单独的 worker 线程,负责事件处理、API 调用和生命周期管理。两个线程之间经过 postMessage 以及 onMessage 进行数据交换,数据能够从 worker 线程传递到 render 从新渲染界面,同时 renderer 也能够将事件传递给对应的 worker 处理。一个 worker 能够对应多个 renderer,方便页面间数据共享和交互。
在资源加载方面,小程序采用离线化方式加载,也就是说当打开小程序时,小程序离线包必须下载到本地,因为每一个版本只下载一次,一方面节省了每次请求的资源开销,另外一方面启动速度大大提高了。当有新的版本时,发布平台自动比对本地安装的版本和最新版本产生并下发差量包,客户端不须要下载整个包便可更新小程序至最新版。
3.3 构建生态
经过引入相同的小程序架构,使得小程序,能够做为生态进行多端互投。在支付宝中投放的小程序,能够只通过一些开放接口的适配,便可跑在基于相同小程序架构的 App 中。将来,开发者或第三方服务更可能是面向小程序来开发,而 App 则是提供一个统一的架构,真正作到开放生态,用完即走的理念。
mPaaS 离线包源自于支付宝原生方案,经历了严苛的业务考验,让你直接和支付宝使用同一套框架层代码,拥有统一容器及内核,相对系统内核获取更低 Crash 率和 ANR 率,适配性强,并具有良好的、弹性的扩展能力,结合具体业务需求定制 JSAPI。
它能够帮助减小 App 白屏、解决 Hybrid App 跨平台兼容与适配,提高 App 性能并大幅优化原生开发下的包大小。
目前 mPaaS 离线包 Demo 源码已更新在 GitHub 上,欢迎 Star:
https://github.com/alipay/mpa...
欢迎申请试用,提更多的优化建议和使用反馈:
http://mpaas2019.mikecrm.com/...
感谢你们能耐着性子,看完我啰哩啰嗦的文章。
在这里我也分享一份本身收录整理的Android学习PDF+架构视频+面试文档+源码笔记,还有高级架构技术进阶脑图、Android开发面试专题资料,高级进阶架构资料帮助你们学习提高进阶,也节省你们在网上搜索资料的时间来学习,也能够分享给身边好友一块儿学习
若是你有须要的话,能够点赞,关注我,而后加入Android开发交流群(820198451)免费领取