写点什么

扩展访问:Uber Lite App开发始末

作者:Harshit Bangar 等

2019 年 2 月 15 日

扩展访问:Uber Lite App开发始末


我们在 2016 年重写的 Uber 乘客 App 带来了丰富的功能和流畅的体验,并支持 Uber 的一系列产品(从 uberPOOL 到 uberXL)和未来体验可扩展性(如JUMP Bikes)。Uber 乘客 App 适用于全球市场,支持 50 种语言和 30 种支付方式,并且这些数字还在增加中。


尽管我们让这个 App 尽可能高效,但它的功能还是导致其体积超过了 60MB,使用了更多的网络带宽,并要求乘客的手机需要具备特定的硬件性能。


尽管越来越多的全球用户在使用我们的新 App,但我们的数据显示,拉丁美洲、印度和中东地区的乘客设备和网络连接常常不能满足要求。例如,56%的 Uber 乘客使用2015年版或更早版本的安卓手机。在这样的硬件上,我们的新乘客 App 可能无法提供最佳体验。我们希望为最广泛的乘客提供服务,尽可能给他们提供最无缝的交通体验。


为了应对这个挑战,我们构建了 Uber Lite(Uber 精简版),这是为那些使用老款安卓设备以及网络基础设施可能无法提供可靠的 LTE 数据连接的地区而设计的。



图 1 在世界范围内,40%的 Uber 乘客使用安卓手机,其硬件相当于 2015 年或更早的版本


开发 Uber Lite 背后的动机


2017 年,Uber 组建了一支团队,成员来自 Uber 的研究、设计、产品和工程团队,旨在解决在低速网络连接地区使用早期版本安卓设备乘客的痛点。在研究人员和设计人员着手了解乘客行为并提出简化的用户界面的同时,工程人员评估了现有的乘客 App,看看是否可以通过重构和精简让它变得更加轻量一些。


深度工程分析显示,只是简单地精简 App 是不够的。相反,我们提出了一个全新的架构,把安卓客户端的通信职责委派给精心编排的轻量级后端,这个后端专门为我们基础架构提供网络调用服务。这个新的移动后端通信模式和信息架构也可以减少带宽的使用,而且不会增加安卓应用程序的大小。


我们的工作促成了2018年Uber Lite的发布,也涉及对全球各地乘客需求的研究,并考虑了他们可用的手机和无线网络。从一系列严格的要求开始,我们的工程团队定下了设计决策,要最大限度地减少应用程序对手机和网络资源的需求。Uber Lite 反映了我们对超越地区和经济的交通需求的认识。


产品设计注意事项


我们最新版的乘客 App 与那些使用最新手机硬件的乘客的需求保持一致,他们能够访问快速数据网络或享受低价的数据套餐。但是,真实世界具有多样性,数据显示,仅仅在印度,就有 4 千 6 百万 Uber 乘客使用安卓手机,这些手机的配置相当于 2013 年或更早的版本。在世界范围内,40%的 Uber 乘客通过安卓手机进行预订,这些手机的硬件可以追溯到 2014 年或更早,而 33%的预订是通过 3G 数据网络进行的。


针对这些情况,为了设计一个高性能的应用程序,我们坚持了这三个指导原则:轻量(light)即时(instant)简单(simple)


轻量


基于我们的研究,我们确定新的 App 应该具备轻量级的观感和操作,下载使用尽可能少的带宽,安装使用尽可能少的内存。


  • 大小少于5MB:把乘客App的下载包大小保持在5MB以下(所需的内存大小小于三张自拍的大小),保存在设备上的则保持在25MB以下,以加快应用程序的安装和下载速度,无论网络环境恶化还是使用2015年或更早的安卓手机都没关系。

  • 点选地图:Uber Lite只显示地图,乘客在必要时选择查看基本的实时地图。这种体验的前提是减少地图的使用,以减少对数据网络的要求。

  • 由****服务器驱动的客户端:Uber Lite使用了一个服务编排层和后端组件来计算和呈现需要从Uber平台获取和编排大量数据的作业。这种工程策略将网络有效载荷减少到不到1个最大传输单元(maximum transmission unit,简称MTU)


即时


新的 App 应该具备很快的响应速度,即使是在 3G 无线网络中。


  • 急切****的要求:新的App要求在两个相继出现的屏幕之间的切换响应时间不超过300毫秒。

  • 保留单一Dalvik可执行文件(Dalvik Executable,简称DEX:在安卓应用程序包(Android application package,简称APK)中的方法总数超过65536个时,就会变成多DEX。智能编译技术的使用与高效库及独立设计相结合确保了Uber Lite可以使用单一的DEX,并具有乘客App所有的核心功能。

  • 实时通知:Uber Lite支持实时通知,可以给乘客传递重要的告警信息。


简单


使用一个简单易懂的 5 步流程为乘客带来良好的使用体验,这样可以获得更好的成行比率(完成的乘行与收到的会话之前的比例),这与使用更强大但在较旧的硬件上或在较慢的网络中性能不佳的应用程序形成了鲜明对比。


  • 引导式接****车:Uber Lite通过使用兴趣点(points of interest,简称POI)而不是输入接车位置简化了目的地的输入。POI往往离新兴区域的实际位置很近,易于司机辨识,使它们成为接车的有用地标。

  • 可点击的目的地:Uber Lite根据乘车人的乘车历史记录和乘车频率呈现目的地列表,并通过缓存它们让乘客能够离线访问并在恶劣的网络条件下进行快速选择。新的App用户界面还可以让用户点击推荐的目的地,而不是让用户输入目的地。

  • 安全:乘客能够轻松地与家人及朋友分享他们的行程,与完整版乘客App中的分享行程状态功能类似。

  • 语言选择:本地化是Uber Lite设计的核心,内置了包括葡萄牙语、西班牙语和印地语在内的多种语言。



图 2 Uber Lite 使用乘客附近的地标简化了目的地输入


App 瘦身


对任意一款应用程序来说,各种库都占据了很大比例的体积,因此,在构建 Uber Lite 时,我们非常关注要包含哪些库。我们仔细评估了大量 Uber 开发库及第三方库的大小、内存和网络使用量。因为我们有独特用例需求,并且对 App 体积和代码方法数量有非常激进的目标,所以我们和不同的内部库作者合作,把它们拆分成更小的模块,这样我们就可以只使用真正需要的功能。我们非常谨慎地选择最基本的已经模块化的库。


例如,我们使用RIBs——Uber 的一个开源跨平台移动架构框架——来实现我们的 App 架构。我们通过 RIBs 的插件框架将乘客 App 的核心代码与非核心代码区分开来,从而形成一个系统,其中的核心流程(基本功能)可以与非核心代码完全隔离。不过,这个框架增加了网络调用有效负载大小。为了避免 Uber Lite 也出现这个问题,我们决定不使用 RIBs 的插件框架。


此外,由于 Uber Lite 涉及的屏幕切换会少一些,因此,我们只在 RIBs 屏幕栈中创建了一些小模块,只包含原生的屏幕切换。这样就可以去掉大约 200KB 大小的额外依赖项。


除了限制库的大小之外,我们还通过以下方式减小 Uber Lite 的体积:


  • 只传送特定于应用程序位置的资源(如字符串),以避免应用程序变得太大;

  • 通过Uber现有的linting结构使用矢量图像格式,避免PNG资源签入;

  • 从合成访问器和协变覆盖等操作生成的Uber Lite字节码中删除多余的方法。


选择架构设计


通过研究其他公司现有的轻量级应用程序,我们看到了三种设计范式:WebView、带有服务器渲染 UI 的原生 App 架构和标准的原生 App 架构。在探索了这三种不同的选择之后,我们决定使用原生 App 设计。


使用原生 shell 虚拟机,并从服务器推送内容和 UI,这意味着 App 二进制文件中不包含产品代码。这个方法的优势是 App 的下载包和磁盘占用空间都很小,并且能够在不导致原生代码膨胀的情况下添加新功能。不过,持续向乘客手机推送 UI 组件会导致网络开销变大,因此,我们探索了以下的替代方案:


  • React Native/Flutter:尽管库很灵活,但其大小在6至8MB之间,所以不考虑这个方法。

  • 通过Uber的移动网站提供WebView:在我们自己开发的Web界面上使用WebView层最初看起来更有吸引力,但在经过试验之后,我们发现了几个问题,如:跨不同安卓版本的碎片化问题、无法整合关键功能、性能低下,以及难以使用现有的移动基础设施。


尽管我们决定使用原生 App 方案,但对于非关键流程,我们仍然使用了基于动态 UI 的框架,这些流程是对核心乘车体验的辅助,例如支付、帮助和支持。


Uber Lite 信息流


对于 App 来说,最慢的操作通常是从网络获取数据,而发展中市场的低网速加剧了这个问题。在构建 Uber Lite 的信息流时,我们用了 8 个关键设计决策来适应 2G 网络:


  • 使用服务器端事件进行后台更新。后台更新对于在不影响乘客体验的情况下保持数据刷新来说是至关重要的。从服务器推送后台更新让我们可以掌控更新的时间和频率。

  • 提前推送信息。上线后立即推送信息(如乘坐的类型和支付选项)可以减少网络调用开销,并通过在离线时也能够在应用程序UI中提供产品信息来改善乘客体验。

  • 在发生变更时推送信息。我们实时推送有关状态变化的信息给应用程序,因此,乘客在司机接受其行程时就收到通知。

  • 每个屏幕只允许一个网络请求。联合网络请求可以提高网络性能,增强乘客体验。

  • 使用单个TCP连接。在2G网络上,其上传速度比下载速度慢得多,单单设置连接就有可能比传输数据要耗费更多的时间。保持数据请求和响应的大小少于1个MTU,以确保只使用一个TCP连接就足够了。

  • 避免冗余通信。避免重复和不必要的信息可以减少网络使用。比如,不要进行定时轮询,而是只在状态变化时发送信息,这样有助于避免冗余通信。

  • 在后端决定操作。让后端决定需要向应用程序发送什么内容,而不是在App中进行不必要的计算。

  • 在客户端缓存数据。Uber Lite缓存静态数据以避免网络调用,如特定用户的产品和支付配置信息。此外,我们还在用户处于wifi网络下以及手机电量充足时通过智能缓存位置信息来实现离线搜索。



图 3 Uber Lite 预加载数据(如可用的产品类型),以免因过度的网络调用而给应用程序带来负担


接下来要做的事


Uber Lite 的旅程才刚开始,我们看好它的未来前景。随着时间的推移,我们将继续构建新的功能,同时寻找方法来控制应用程序的大小,并坚持我们的设计原则:轻量级、即时和简单。下面,我们来讨论一些未来 Uber Lite 要添加的内容。


用于非常规流的 WebView/动态 UI


我们开始研究如何为了某些非常规流在 App 中使用 WebViews 或动态 UI 框架。我们希望在 WebView 中尝试不同的缓存策略,让它们在慢速网络中更快地运行。优化缓存应该有助于 App 在不影响其大小的情况下进行扩展。选择原生体验还是优化 App 大小是一种有意识的权衡,我们希望保持本地用户最重要的流并提供更流畅的体验。


ProGuard、ReDex 和应用程序包


我们也在探索第三方库瘦身策略。尽管我们可以轻松地清除 Uber 自身的内部库,但是像 ReactiveX 和 Dagger 这样的开源库仍然是 Uber Lite 大小的重要组成部分。我们已经使用ProGuard来优化 APK,同时也在积极寻求使用 ProGuard 和ReDex进行进一步优化。与此同时,我们也在探索新的解决方案(比如 App 捆绑包)以便能够快速发布新功能。


工具


保持小体积的 App 不是件容易的事情,一次大的提交就可以摆脱我们的大小限制。为了保持我们的设计原则,我们积极致力于开发工具来避免多 DEX 文件、生成 App 大小指标、删除未使用的依赖项,以及提供依赖包白名单(这些白名单依赖包通过传递性避免了多余的依赖项)。我们还增强了 CI 管道来抛出这些错误,这样开发人员就可以获得拉取请求时实时反馈。


查看英文原文:Expanding Access: Engineering Uber Lite


2019 年 2 月 15 日 08:001364
用户头像

发布了 199 篇内容, 共 65.1 次阅读, 收获喜欢 272 次。

关注

评论

发布
暂无评论
发现更多内容

移动生态盘点与HMS生态解析

华章IT

华为 Android Studio 移动开发 HMS

如何基于 SDK 快速开发一款IoT App 控制智能灯(iOS 版)

IoT云工坊

ios App 物联网 IoT sdk

没能进入大数据领域

escray

面经 面试经历 101次面试

高空立体云防控系统搭建,智能化平安小区建设方案

t13823115967

平安小区 智慧平安社区建设

APICloud AVM多端开发案例生鲜电商app深度解析(上)

APICloud

Vue Web Worker 前端框架 移动终端 前端训练

华为18级工程师总结的50W字算法、LeetCode、操作系统、计算机底层刷题必备笔记

Java成神之路

Java 程序员 架构 面试 编程语言

星域母子币系统软件开发|星域母子币APP开发

开發I852946OIIO

系统开发

为什么说rollup比webpack更适合打包库

fengxianqi

前端 Rollup webpack

一线大厂开源三份JDK+Spring+Mybatis源码笔记

Java架构追梦

Java spring 源码 jdk mybatis

Java:利用BigDecimal类巧妙处理Double类型精度丢失

程序员小毕

Java 架构 编程语言 阿里 开发

微服务架构思考 - 理清楚,管起来

jorden wang

Github、知乎下载超过 28762W 次的 Java面试题库(附答案)

Java成神之路

Java 程序员 架构 面试 编程语言

直播中不可缺少的一环-rtmp直播推流

anyRTC开发者

音视频 WebRTC CDN RTC RTMP

盘点 2020 | 10 天开发前台系统技术系列

老魚

CSS 前端 全栈 js 盘点2020

字节二面跪拜“Redis源码”后,面试官直接推荐这份笔记!真是NB

比伯

Java 编程 架构 面试 程序人生

限时!字节Java程序性能优化宝典开源,原来这才叫性能优化

996小迁

程序员 面试 性能优化 笔记

云视频技术领军人赵加雨:如何提升在线教育课堂互动体验

拍乐云Pano

音视频 在线教育 RTC 互动课堂 白板

抢先体验全新升级版Eternal Wallet!

Geek_c610c0

数字货币 数字货币钱包开发

区块链溯源平台优势,区块链溯源系统解决方案

13530558032

加密猫MIMI系统APP开发|加密猫MIMI软件开发

开發I852946OIIO

系统开发

智慧社区综合管理平台搭建,智慧平安城市建设

13530558032

周立齐出任电动车联合创始人:网红经济背后的病态消费心理

石头IT视角

为什么香港云服务器更适合放新网站

德胜网络-阳

阿里P9都赞不绝口的面试宝典!半月看完25大专题,居然斩获阿里P7offer

Java成神之路

Java 程序员 架构 面试 编程语言

本科毕业,六年Java开发经验,阿里技术三面+HR面,拿下38*16薪资P7offer

Java成神之路

Java 程序员 架构 面试 编程语言

应急指挥中心平台搭建,移动可视化指挥解决方案

t13823115967

可视化数据分析搭建 应急指挥

九环智能合约开发

V19927655815

APP开发

扒开 SqlSession 的外衣

田维常

mybatis

阿里P8亲授MySQL学习教程笔记,一个月吃不透那我真的白活了!

Java成神之路

Java 程序员 架构 面试 编程语言

如何通过 Serverless 轻松识别验证码?

Serverless Devs

人工智能 Serverless 云原生

重点人员管控系统开发,情报研判系统开发

13530558032

扩展访问:Uber Lite App开发始末-InfoQ