移动动态化方案在蜂鸟的架构演进(含React Native与Weex对比)

当下,移动动态化已经成为各大公司都回避不了的问题,产品的快速迭代对技术提出了更高的要求,而移动端的动态化方案也是层出不穷:Hypid、结构化 Native View、React Native、Weex,什么样的方案才是适合本身团队的呢?本文将分享饿了么蜂鸟团队在过去两年多业务快速增加过程当中,移动动态化方面的实践和探索。前端

什么是移动动态化?

移动指的是移动端,包括安卓、iOS。动态化则是动态部署和逻辑下发到客户端的能力。移动动态最好的状态就是让移动应用和 Web 同样,想发就发!性能优化

为何移动端要强调动态化的能力?网络

缘由有以下三大点:架构

  •     业务迭代太快。当下大部分团队都是敏捷开发的模式,即便两周作一次迭代,产品周期仍是会以为长,有些应用不能及时上线。框架

  •     应用市场审核慢。安卓基本当天发应用市场,当天就可以有更新。但 iOS 须要约 3-4 天来审核。假设有些功能须要定时上线,iOS 审核时间必需要考虑进去。ide

  •     用户升级周期长。统计代表,每个安卓版本发布,一周内会有 70% 的用户更新,一个月其他用户才能陆续完成更新。工具

移动动态化方案共性,有以下三点:组件化

  •     跨平台。布局

  •     布局。约定 DSL,保证渲染性能。性能

  •     逻辑。Android 和 iOS 必须共用解释器。

蜂鸟团队的现状与业务特色

蜂鸟团队现状

蜂鸟团队于 2014 年成立,初衷是为了承接饿了么的物流业务。随着时间推移,订单量从每日几千单到百万单,配速员也达到百万数量,服务品类涉及外卖、商超、鲜花、蛋糕、文件等,蜂鸟提供全时段配送,配送服务覆盖全国 1200 多个城市。

蜂鸟团队的业务特色

蜂鸟团队的业务主要有离散性和突发性两大特色,以下图:

从业务曲线能够看到两个很明显的波峰,这是午、晚用餐时间。同时,若是运营方面配置一些活动,会致使这两个波峰徒增。因此,动态方案要想把这两个时间段服务好,必需要考虑流量陡增下的性能压力。

蜂鸟团队的技术特色和挑战

蜂鸟团队的技术特色和挑战,我主要分享重度依赖、网络环境复杂、重度使用和 28 定律这四个方面。

重度依赖

当前蜂鸟有众包、团队和送送三部分业务,右侧是一些功能展现,以下图:

这样的工具型应用,须要对 APP 有更强的控制、监控等能力。必要时还要作到强制更新。

对应到动态方案的话,控制能力就须要动态方案必须具有动态降级的能力、监控能力,实时的性能监控和业务埋点监控。强制更新方面,动态方案必须作到用户无感知的热更新。

网络环境复杂

饿了么小哥,天天穿梭在大街小巷、地下商超,他们的网络环境很是不稳定。据统计,有近 25% 的用户请求还来自非 4G 环境。

总体来讲的网络环境复杂、信号差和 DNS 污染,那么动态方案就要解决 DNS 拦截、弱网环境下资源下发等问题。

重度使用

不管是下雨、下雪,仍是发洪水你们都会叫饿了么。

配送员在高峰期的运动曲线,以下图:

面对这样争分夺秒的准时达压力,若是动态方案不给力,会致使应用出现崩溃或卡顿,骑手一定不会有好的体验,甚至影响送餐时间。因此咱们的动态方案必定要保证性能和稳定性。

28定律

相信不少公司的应用都符合相似 28 定律,蜂鸟也不例外。

以下图,蜂鸟的 28 定律

能够从图中看出,大部分骑手平常使用的主流层面,能够采用 Native 来开发,这部分重度使用的占比约 20%,其他 80% 的功能均可以考虑动态化方案(H5)。

蜂鸟团队的动态化架构演进

蜂鸟的动态方案通过 Hypid、React Native 和 Weex 三个主要阶段。

第一阶段:Hypid

在 Hypid 方案上,以 H5 的动态性为基础,经过 Jspidge 作桥梁,与 Native 进行通讯,以后经过 URL Router 进行跳转,架构以下图:

这套动态方案的优势显而易见,这里主要介绍开发效率、更新体验和跨平台三方面:

  •     开发效率。Web 通过多年的应用实践,已经拥有完整的开发流程和开发工具,开发一个 H5 页面很是快速。开发效率这一因素不能忽略,由于初期产品的想法和落地速度会直接影响产品的命运。

  •     如蜂鸟送送,初期没有原生的资源去支撑,就用原生包壳,内部所有用 H5,这样的状况坚持了两月左右,为蜂鸟送送前期的方案验证作了很大的贡献。

  •     更新体验。因 H5 和原生耦合只有扩展的 Native API,只要把这些 API 维护足够全,开发的业务功能就能够在彻底不用更新 APK 的状况下,作到热更新。且用户下一次打开应用是最新的,这和 Native 的升级体验相比简直是一天一地。

  • 跨平台。以前安卓和 iOS 代码须要开发两次,如今一个功能决定用 H5 后,由一个工程师来开发一套代码便可。

这套动态方案很大的缺点就是用户体验差,当用 H5 作一些复杂的功能或动画时,可能会卡顿的和 PPT 同样。由于 H5 的体验问题,蜂鸟的原则是常常更新的且功能不复杂的页面会选择用 H5。

第二阶段:React Native

这个动态方案彻底脱离了以 H5 为基础的 Hypid 方案,经过自定义 DSL 将 UI 渲染成原生控件,这样一来, RN 的页面就保证了原生的体验和 Web 的效率。

除了上一点,还有组件化开发、复用率高、Android 和 iOS 95% 的代码共用和测试效率高等优势。

鉴于这些优势,蜂鸟在 React Native 上作了不少事情,如 Crash 优化、基础控件沉淀、Bundle+ 图片热更新、首屏加载优化和 Redux 单项数据流等。

正当享受 React Native 带来的开发体验和应用体验提高时,蜂鸟遇到 RN 的一些痛点,如 ScrollView 性能、Bundle 包过大、不少优化都须要修改源码和 peaking change 等。

第三阶段:WEEX

面对如上这些痛点,不知如何应对时,WEEX 来了。官方宣传的轻量、可扩展和高性能等特色,让蜂鸟团队眼前一亮。

经深刻研究后,蜂鸟发现 WEEX 和 React Native 一模一样,那么为何要选择相似的方案呢?

咱们队 WEEX 和 React Native 二者基于 JS 引擎、语法、数据流、性能、开发体验及热更新等维度进行了对比。

以下图,是 WEEX 和 React Native JS 引擎对比

React Native 在安卓和 iOS 使用的都是 JsCore,WEEX 在安卓端使用的是 UC 精简版 V8。如上图中的图表能够看出,V8 相比 JsCore 要胜一筹。

WEEX 和 React Native 语法对比。语法方面,React Native 使用的是 React,WEEX 使用的是 Vue。虽然两套方案都实现了如响应式,组件化、状态管理等功能。

以下图,是二者简单 Demo 的实践:

实践发现,WEEX 相比 React Native 要优雅一些,是由于 Vue 有不少自定义标签,当在作一些 UI 和逻辑交杂在一块儿时,会让代码简洁不少。

 WEEX 和 React Native 的数据流对比,React Native 使用 Redux,而 WEEX 使用 Vuex,不是 WEEX 不能使用 Redux,而是 Vuex 更适合 WEEX。

以下图,是二者的数据流,大同小异:

但 Vuex 在实现一些计算属性时,能在更细的颗粒度去更新 UI,而 Redux 只能实现到组件的级别,这样的点不少的话会带来性能上的差别。

以下图,是 WEEX 和 React Native 的性能对比,左侧是 WEEX 官方给出的与 React Native 在性能方面的对比图:

在渲染时间和内存占用方面 WEEX 要优于 React Native,在 CPU 占用方面二者相差不大,FPS 上 WEEX 要稍逊于 React Native。

在 ListView Android 方面,React Native 目前采用 ScrollView,WEEX 使用 Recyclerview 实现,性能稍好。

同时 WEEX 在加强开发、指定线程、首屏渲染和性能监控等方面也作了优化。

以下图,是 WEEX 和 React Native 的开发体验对比

和 React Native 相比,WEEX 在打包、监控性能、跨平台等方面都有必定优点。整体来讲,React Native 更像是一个技术框架,WEEX 更像是一个业务框架。

以下图,是 WEEX 和 React Native 的热更新对比:

React Native 与 WEEX 官方都表示支持热更新,但他们的实现方式不一样。在 React Native 上可经过把图片打包下发到本地来实现更新。

WEEX 有两个方法,一是选择本地资源加载,二是像网页同样直接加载页面。

以下图,是 React Native 与 WEEX 的对比总结

React Native 更像一个先驱者,拥有超强的社区人气,但也因开源社区维护代码的缘由处于一个野蛮生长的状态。而 WEEX 是站在 React Native 的肩膀上,作了各类微创新,实现更多贴心的小细节。

基于 WEEX 性能、稳定性等方面都比 React Native 高,蜂鸟决定把动态化方案往 WEEX 上迁移,虽然它如今还有不足,有些轮子仍是要本身去作。

蜂鸟团队 WEEX 实践

凭借以前 React Native 相关的实践经验,基于 WEEX 作了一套更完整的动态方案。涉及如下几个方面,以下图:

统一的pidge 

在 Android & iOS 端,约定相同的方法名、参数,在 JS 层抹平平台差别以及统一分类管理暴露给业务的 API。

把这样的统一 pidge 方案提供给业务部门,他们只需关心暴露的 API,而不须要关心下一层平台的兼容,大大提高开发效率。

加载更新策略

加载更新方面,咱们约定了一套自有协议,有 Page、URL 和 Tag,经过封装的 Router,就能够作到页面级的跳转。

这样一来,咱们很轻松地作到了页面的跳转、解耦和页面的降级。当页面出现问题,只须要把 URL 改为降级以后的 H5 页面下发便可,用户触及到的就是修复以后的 H5 页面了。

以下图,是预加载策略

当 H5 页面下发到客户端以后,会对本地资源进行检查,若是有 JS 文件,就忽略,没有的话就把页面下载。当用户打开页面,再去看本地,存在资源的话直接加载,不存在的话就即时下载再运行,与传统的 Web 流程类似。

性能监控

性能监控用来判断线上服务是否正常,是整套方案最重要的部分。

WEEX 能够很方便地将全部的参数所有拿到且经过反射拿到全部的性能数据传到云端。

基于这些数据,咱们就能够知道线上有了哪些页面,它的渲染是否有问题。基于这些问题,就可作相应的优化。

以下图,是线上的数据状况

监控三个指标,分别是 JS 引擎的初始化时间、页面打开时间和网络时间。因大部分 WEEX 页面都是业务,因此说业务埋点必不可少。饿了么也实现了一套框架,将业务埋点传给服务端,而后方便产品去制定一些产品方面的策略。

JS 的错误统计

能够捕捉 JS 端抛出的错误,若是所处团队是前端主导,可传给前端。若是是 Native 主导,可经过搜集平台将这些崩溃上传,在后台看到这些错误以后,找到相应的代码去修复。

Native 的错误

有了 JS 错误,Native 错误也不能忽略。

以下图,是 WEEX 动态方案上线一周以后线上抛的错误:

从图中能够看到都是个位数,这一点其实当时也很惊讶,WEEX 确实作得很稳定,这一点超出预料。

共用组件和 API

以前蜂鸟在 React Native 上面的一些实践,积累了一些很经常使用的组件和 API。WEEX 和 React Native 都是使用 JS 实现,因此咱们很方便的将 RN 的控件转化为 WEEX 控件。

以下图,是实现的组件和 API,几乎能够知足中小团队的平常使用:

调试工具

这方面 WEEX 作的很贴心,虽然没有整合到整个初始化的项目中,但开源了几个库,可把代码拷贝到业务中进行使用。

WEEX 还可支持 Debug 模式显示调试工具、支持 hot reload、方便的查看性能指标和 Shell 脚本一键打包等功能。

综上所述,基于这些维度实现的框架,能够方便的让业务来使用。

以下,是饿了么和蜂鸟用 WEEX 实现的两个页面:

饿了么的第二个发现页面,就是基于 WEEX。蜂鸟 APP 可能你们接触不到,上图是当前通知的活动界面,还有大量的新功能正在接入。

若是你正在考虑 WEEX 与 React Native 方案,或是正在接入 React Native。看到这篇文章,你能够去调研如下 WEEX 方案,可能你会有另外一种选择。

以上内容根据许锦洋老师在 WOTA2017 “移动端架构演进”专场的演讲内容整理。

负责饿了么蜂鸟 APP 的架构、研发等工做。拥有饿了么商家、风行者、蜂鸟众包等多款 APP 开发工做经历,并从 0 开始架构和开发了整个蜂鸟团队 APP。目前关注的技术方向为移动跨平台技术方案、移动端架构、移动端性能优化等。

相关文章
相关标签/搜索