1.导读
随着移动互联网的成熟发展,移动应用技术上呈现出多样化的趋势,业务上倾向打造平台及超级入口,超级应用应运而生。但业务快速扩张与有限的系统资源必然是冲突的,如何实现多(能力服务的高增长)、快(体验流畅)、好(兼容稳定)、省(资源成本低),让大象也能跳舞,成为摆在超级应用面前必须解决的问题。
伴随着高德地图APP近几年的高速发展,也面临到这些问题,从2019年开始,我们开启了一系列性能优化专项,对高德地图APP进行了深入性能分析和极致优化,取得比较显著的效果。在这个过程中总结了一系列优化思路和技术方案,希望对同样面临超级应用性能问题的你有所帮助。
经过一系列优化动作,我们在保证业务需求正常迭代新增的基础上,启动、核心链路交互、行中内存、包大小等多方面均实现了性能的成倍提升,尤其是低端机上达到了3倍+的提升,从多个维度改善了用户性能体验。
- 启动攻坚:启动耗时降低70%+,实现2s地图元素完成展示,并管控保持在稳定低水位,呈下降趋势。
- 核心链路交互优化:在搜索、路线等链路上实现中高端机型秒开、低端机型2s内打开,整体提升用户流畅交互体验 。
- 行中内存优化:全机型优化了30%左右,提高稳定性。
- 包大小攻坚:双端体积降低20%,提高安装转换率。
2.性能优化业务背景
某段时间,高德地图APP面临着性能恶化、管控困难的问题。以启动耗时为例,双端启动等待体感明显,并且历史上治理后出现反复,整体呈上升趋势,我们思考问题背后的问题,主要有以下几个方面:
业务庞大
超级应用一般都经历这样的发展过程。首先,应用提供服务给用户,用户开始增长,增长的用户会产生更多的需求。应用为满足新增需求不断迭代,提供新的服务。新的服务推动用户进一步增长,进入下一个循环。正是在这个正循环发展中,应用像滚雪球一样越滚越大,终于成为超级应用。
然而,随着业务需求的不断增长,业务量和复杂度也随着上升,系统资源会越占越多。但机器资源是有限的,资源的争夺不可避免地会导致性能问题,从而影响用户体验和业务扩展,成为超级应用正循环发展的拦路虎。
高德地图也同样经历了这样的过程,随着这几年的快速发展,应用从手机扩展到了车机,平台从iOS、Android扩展了Windows和Liunx,覆盖10多种出行方式的同时,还在不断提供组队、视频、语音、AR等新服务。与此相应的是单端代码行超百万行,线程上百,任务上千,造成了持续的性能压力。
环境复杂
性能问题面临的另一个主要挑战是超级应用的环境复杂。一方面,随着移动设备的长线发展,系统碎片化情况越来越严重,Android系统横跨11个主版本,iOS横跨14个主版本,加之设备厂商对系统进行各种各样的改造,进一步增加了系统的碎片化;另一方面,用户移动设备的环境是非常不稳定的,电量、温度的变化以及其他应用的抢占都会造成内存、CPU、GPU等资源波动。复杂不可控的环境为一致的性能体验的保持增加了很大的难度。
但作为大用户体量的超级应用,任何环境的体验都要保证。特别是地图领域,用户习惯对不同产品直接对比,任何环境下性能体验问题,都会直接影响产品的整体口碑,导致用户流失。所以需要兼顾所有环境,不只是主流机型系统和场景,在长尾场景与机型系统上也必须流畅运行,这就要求超级应用这头大象不但要在舞台上跳舞,在凳子上、甚至在水里也能跳舞。
技术链路长
为了满足研发效率提升、产品动态化等多样需求,移动应用技术上除支持原生开发外,也要支持小程序、Web H5、C基础库等跨平台、容器化、动态化开发。从高德APP来看,最顶层业务除了OC、Java外,还支持JS开发。支撑层提供了AJX、小程序、原生、C等多种容器框架,同时还涉及JS、JNI等桥接层。最下面则用C++提供地图各个引擎能力,这里包括OpenGL、定位传感器融合等多种底层能力。技术链路自上而下开始变得长且复杂,链路上任何一环都可能导致性能问题,原有的单技术语言的排查工具已经无法定位明确性能卡点模块,为性能排查和管控带来挑战。
3.解法:低成本优化迁移,长线管控
基于上面的问题,原有传统的一招鲜的优化方案,显然解决不了需求日益增长和复杂环境下的性能一致体验。所以,我们在专项实践过程中,沉淀了一套自适应资源调度框架,解决历史性能问题的同时,能够在不影响现有的研发效率的情况下,低成本优化迁移,实现新业务高性能的开发。此外,从系统底层进行全维度资源监控,自动定位分发问题,来实现长线管控,避免先治理后反弹的情况。
自适应资源调度框架
自适应资源调度框架在应用运行过程中,感知采集运行环境。然后对不同环境状态进行不同的调度决策,生成相应的性能优化策略,最终根据优化策略执行对应优化功能。与此同时,监测调度上下文以及调度策略执行效果,并将其反馈给调度决策系统,从而为进一步的决策调优提供信息输入。这样,可以做到在不同的运行环境下都能达到可预期的极致性能体验。并且,整个过程,对业务无需额外开发,做到无感接入,避免影响业务开发效率。
• 环境感知
感知环境分为硬件设备、业务场景、用户行为和系统状态四个维度:
- 硬件设备上,一方面通过集团实验室对已知设备进行评测跑分确定高中低端机型,另一方面在用户设备上本地对硬件进行实时算力评估。
- 业务场景上,将业务分为前台展示、后台运行、交互操作等几类,一般情况下前台正在进行交互操作的业务场景优先级最高,后台数据预处理业务场景优先级最低。对于同类别业务场景,根据业务UV、交易量、资源消耗等维度进行PK,确定细分优先级。
- 用户行为上,结合服务用户画像和本地实时推算,确定用户功能偏好和操作习惯,为下一步针对用户的精准优化决策做准备。
- 系统状态上,一方面通过系统提供接口获取诸如内存警告、温度警告及省电模式等来获取系统极端状态,另一方面通过对内存、线程、CPU和电量进行监控,来实时确定系统性能资源情况。
• 调度决策
感知到环境状态之后,调度系统将结合各种状态与调度规则,进行业务以及资源调配决策:
- 降级规则:在低端设备上或者系统资源紧张告警(如内存、温度告警)时,关闭高耗能功能或者低优先级功能。
- 避让规则:高优先级功能运行时,低优先级功能进行避让,如用户点击搜索框时到搜索结果完全展示到时间段内,后台低优任务进行暂停避让,保证用户交互体验。
- 预处理规则:依据用户操作及习惯进行预处理,如某用户通常在启动3s后,点击搜索,则在3s之前对该用户搜索结果进行预加载,从而在用户点击时呈现极致的交互体验效果。
- 拥塞控制规则:在设备资源紧张时,主动降低资源申请量,如CPU繁忙时,主动降低线程并发量;这样在高优任务到来时,避免出现资源紧缺申请不到资源性能体验问题。
• 策略执行
策略执行分为任务执行和硬件调优:其中任务执行,主要是通过内存缓存、数据库、线程池和网络库对相应任务的进行运行控制,来间接实现对各类资源的调度控制。而硬件调优,则是通过与系统厂商合作,直接对硬件资源进行控制,如CPU密集的高优业务开始运行时,将提高CPU频率,并将其运行线程绑定到大核上,避免线程来回切换损耗性能,最大化地调度系统资源来提升性能。
• 效果监测
在资源调度过程中对各个模块进行监测,并将环境状态、调度策略、执行记录、业务效果、资源消耗等情况反馈给调度系统,调度系则统以此来评判本次调度策略的优劣,以做进一步的调优。
全维度资源监控
由于技术链路长、关联模块复杂,原来出现性能问题时,需要所有相关方集中排查,check所有的改动代码,依赖个人经验判断代码的成本来定位问题,协作和排查成本都很高,导致性能管控有效落地阻力很大。所以我们就思考,性能问题的根本是硬件资源的竞争,那能不能逆向解题,反过来对资源成本进行监控,如果发现异常再回溯产生成本的代码,以及分发给相应owner.
那基于这个思路,在构建的时候,首先通过代码扫描建立代码模块关联库。然后,进行成本和调用栈采集。采集完成后,对基线版本和当前版本的成本进行对比,如果发现异常,则通过符号反解异常成本的调用栈直接定位到问题代码。另外,基于问题代码查找代码模块关联库,来定位问题模块,最后将问题准确分发给模块相应的owner,最终实现问题的自动定位和分发,支持团队并行解题。
管控流程体系
性能的有效长线管控,除了上面的资源监控平台,还需要配套的流程体系及组织保障。所以在APP的生命周期每个阶段都建立了从测试分析到修复验证的闭环管控。前置监控在迭代开发阶段,早发现早解决。在集成阶段监控每一个改动,保证及时处理。线上通过实时监控和动态下发,实现快速修复。
4.总结与思考
决心大于方案
超级应用的性能问题往往关联多方业务,需要多方团队协作,所以自上而下对性能的重视程度和优化决心是决定成败的关键,打通任督二脉,才能事半功倍,把优化方案顺利落地。
攻城难,守城更难
业务与技术都在快速迭代,要想保证优化成果防止反弹,管控是必须的,而管控就会有束缚和效率影响,管控过程中就难免会遇到各种各样的阻力。所以一方面技术上,建立标准规则,配合提效工具和优化流程,尽量避免影响业务开发。另一方面,团队需要具有共同认知,性能体验与功能体验同等重要,用户对比心智很强,性能体验往往与产品口碑直接挂钩。
性能优化永远在路上
目前,我们很多优化策略以及数据参数还是从实验室调校而来。未来,我们会进一步探索云端一体、端智能等技术,做到更懂用户,贴合业务和用户特点,实现性能体验的个性化提升。