高德地图从19年开始对全链路性能体验进行了持续三年的优化,最终整体核心链路上实现了打对折优化,用户体验上大幅提升。过程中,对性能优化的一些思考和实践经验,本文进行了总结,希望对大家有些助益。
优化前后效果对比(以优化前的耗时为基线100%)
整体思路分为明确性能卡点,倒序专项解题和正序长线管控三个部分:
接下来,本位将针对这三个部分,逐一解析。
首屏加载速度的快慢极大影响着用户体验,所以首屏耗时作为我们页面耗时的统计标准。随着手机硬件的不断升级,很多高端设备硬件性能好掩盖了程序性能问题,因此我们会对不同机型等级设备进行优化,最大程度的覆盖到线上用户。
确定了首屏显示耗时是统计标准,下面是如何确定首屏显示耗时的几个维度:
高德地图长期以来的历史累计,导致每个场景的优化,都面临着复杂的业务代码,甚至还存在业务盲区。这就对快速分析历史大量业务,精确定位耗时点带来极大的挑战。如果靠人工梳理分析,人力投入和时长都不现实。这就需要从工具和方法论上找到加速方案。
无限的业务场景通过移动设备运行在有限的性能资源上,资源分配势必捉襟见肘。所以我们需要根据设备的不同来分析耗时问题。比如在比较差的手机上出现的耗时问题,可能在高端的手机上并不是问题。优化点也不同,需要个性化策略来进行针对性优化。例如:低端机的复杂交互动画就是一个耗时点,比如搜索页面关闭一些动画,性能上带来不小的收益,同时也不损害用户体验,在高端机上这个耗时点就可以不考虑。
业务点特别多,那么为什么我们要选择出行场景、搜索场景等去分析耗时呢?这就需要拉通产品和BI,用数据说话。通过分析线上用户行为,大部分用户选择了点击搜索框进入搜索首页,而线上用户反馈也是进入搜索卡顿耗时等,相比其他功能,搜索首页的及时性和重要性不言而喻,于是根据线上数据进行业务分级,该场景排在首位,性能资源应该向这里倾斜,需要首先分析这里的耗时点。
首先对业务场景本身进行全链路梳理,找出其中的关键时间点,然后通过场景日志工具进行埋点并上传至服务,收集线上用户真正的首屏时间数据,为量化目标提供有效依据。其中两两关键点之间的时间戳差值即为阶段耗时,能辅助分析业务耗时问题。围绕着业务分析的过程我们还沉淀了很多分析工具来辅助分析。
最小集是一个探底的过程,在保证首屏产品形态不变形的情况下做出最小可运行,去掉其他所有跟首屏无关项,这就是减法。我们可以理解这个最小集是在不改变现有架构的情况下,我们最优的优化效果。如果最小集的极限数据达标,接下来就要在此基础上把必要的相关依赖项逐个加回来,保障产品功能完善,其他没必要的依赖性可以优化、或者去掉、或者延后等,这就是加法。当然如果这个最小集的极限数据都不能达标,那我们就需要从其他维度去寻找优化点了,一般能够从网络耗时和架构合理性两个方面找到突破点。
性能问题不是单一业务问题,往往涉及多个产研测团队协作。所以我们的思路是:
从问题出发快速倒序以专项形式凝聚多团队资源,确定目标,快速攻坚拿结果,增强团队信心
专项攻坚,也是个边打边建,边打边沉淀的过程。排查性能问题的手段最初是比较离散的。往往是遇到一个解决一个,下次不同的场景需要重复工作再来一遍,那么我们的思路是:
沉淀可复用方案,解题思想、通用框架和工具平台,针对“优化手段”本身的效率进行优化,让成本逐渐降低
启动专项是第一个性能专题项目,完成了一个场景优化,耗费30人,3个版本迭代。之所以人力比较多,是因为“第一次”面临的问题非常多,指标要分析定义标准、埋点工具要新建、优化过程没经验、管控手段要新建。
搜索专项完成了一个场景优化,耗费8人,人力情况就好了很多,版本变成2版。当时已经有启动期间已经建设好的埋点工具,有了一定的优化经验,少走了很多弯路。
核心链路专项完成了六个场景,耗费24人,一版搞定。优化的过程有条不紊,人力少、场景多、时间短。这得益于优化效率的提升,成本逐渐降低。在不断优化的过程中积累了相对成熟的分析工具、优化工具、管控工具。
性能优化是一个体系化问题,我们在优化方案上分为三层,业务、引擎和基础能力,分别自上而下明确优化点。上层业务进行自适应资源调度,中间引擎提供加速能力,底层能力提供高性能组件。
业务层优化主要通过业务编排调度来实现性能最优状态,但业务各自调度优化工作重复且繁琐。为了降低这部分成本,我们开发了一套资源调度框架,业务接入后,调度工作由框架完成。调度框架在应用运行过程中,感知采集运行环境,然后对不同环境状态进行不同的调度决策,生成相应的性能优化策略,最终根据优化策略执行对应优化功能。与此同时,监测调度上下文以及调度策略执行效果,并将其反馈给调度决策系统,从而为进一步的决策调优提供信息输入。这样,可以做到在不同的运行环境下都能达到可预期的极致性能体验。
感知环境分为硬件设备、业务场景、用户行为和系统状态四个维度:
感知到环境状态之后,调度系统将结合各种状态与调度规则,进行业务以及资源调配决策。
策略执行分为任务执行和硬件调优:其中任务执行,主要是通过内存缓存、数据库、线程池和网络库对相应任务的进行运行控制,来间接实现对各类资源的调度控制;而硬件调优,则是通过与系统厂商合作,直接对硬件资源进行控制;如CPU密集的高优业务开始运行时,将提高CPU频率,并将其运行线程绑定到大核上,避免线程来回切换损耗性能,最大化地调度系统资源来提升性能
在资源调度过程中对各个模块进行监测,并将环境状态、调度策略、执行记录、业务效果、资源消耗等情况反馈给调度系统,调度系统则以此来评判本次调度策略的优劣,以做进一步的调优
地图引擎是地图应用独特的部分。这块主要从绘制优化策略入手,主要包括分批分块渲染、帧率调度、消息调度等。
跨端引擎则需要给业务提供支撑,它也是全场景通用的方案,比客户端优化更有施展空间,与业务直接接触离业务够近。所以跨端引擎的优化策略就是降低业务代码的性能成本。主要方案有:
这里简单介绍下上下文预加载,为了不影响现有业务的运行状态,我们设计了一种闲时分段预加载的方案,能够在页面未进入之前,将页面需要计算的耗时、导入文件的耗时等提前执行。
1、离线包加速
离线包加速,主要解决复杂 H5 页面的加载速度问题:资源文件数量较多,下载耗时较长,导致页面加载缓慢,通常通过增加loading来减少界面加载等待问题,从而导致用户等待耗时长,最终带来的是转换率流失。在此大背景下,结合高德已有的一些平台能力,搭建了离线包加速能力。整个链路包含:
2、容器预创建
容器的预创建和预热,对于H5页面的加载速度将会有很大的提升,WebView的实例创建成本本身是相对较高的,在APP启动后合适的时机进行预创建并缓存复用,可以解决首次开启和二次加载的速度。AMap本身有启动任务编排及闲时任务调度,在此基础上可在对应WebView模块内进行预创建操作。对于预创建WebView Context切换问题,由于AMap的页面栈实际为自定义实现,仅有一个独立的Activity,因此具有天然的良好兼容性。对于预创建,本身是空间换时间的一种做法,对于不同性能设备的差异化配置,需要重点打磨——此外,也可以结合端智能的特征行为,类似用户页面跳转的行为习惯及频次等,来动态决策是否需要进行预创建。
线程池支持业务进行任务优先级编排、线程总数控制、线程避让等调度策略,使设备资源得到充分合理的利用。
线程队列管理模块,其提供5个优先级队列:
网路请求作为场景中耗时大头,其性能表现几乎决定了场景首屏耗时表现,我们针对网络请求的各个环节,做了链路监控与极致优化,重点包含:请求精细化调度、并发预处理、DNS预加载、连接复用等。
请求链路示意图:
优化是从“果”倒退“因”的过程,已经发生问题了再去解决,是一种倒序解题的思路。那么如何让问题从“因”的源头上截住,或者说让已经优化的效果不发生倒退,那么我们的思路三是:
长线持续的正序管控,避免原有业务的持续恶化,同时巩固专项的优化成果。
高德地图客户端横向业务上包含出行、搜索、打车等业务线,纵向架构上包含业务层、平台适配层、跨端引擎层和地图引擎层,跨多个语言栈,性能问题具有跟进流程长和排查链路长的特点。因此管控思路集中在标准、流程、自动化平台和工具的建设上。
在经过全面的专项治理后,性能管控的目标和要求是避免持续恶化的状态,由于测试波动的存在及热更、快速迭代、动态化插件的频繁发布,需要管控的出口非常多,如果存在管控遗漏区,性能就会不可避免的持续恶化。因此管控标准确定为以固定基线为基准,以环比数值为量化标准,把所有变化因素都包含到管控中,有效防止叠加恶化。
高德客户端主版流程主要分为三个大阶段:需求分析和设计、业务独立迭代开发、集成测试,集成测试阶段本身有大量的业务BUG,所以留给性能问题发现和解决的时间非常紧张,为了解决这些问题,管控流程需要利用好主版流程的每一个阶段,分阶段消灭性能问题。
依托泰坦持续集成平台和ATap自动化测试平台,打造连通开发,构建,性能测试,问题跟进、排查、流转、解决完整链路的工具链,提高问题发现和解决的效率。
泰坦持续集成平台
定时构建,支持定位出包任务,构建类型支持性能包
自动化测试触发,支持打包触发和定时触发两种触发方式
集成卡口及决策,集成申请展示性能测试结果,集成决策审批流程
ATap自动化测试平台
性能大盘,汇总性能数据,快速发现问题
埋点详情,整合快速排查工具,加速排查
问题跟进,结合Aone,监控问题解决流程,加速流转
目前为止,高德核心链路的性能体验优化效果得到了较大的提升。从最初的拿到优化结果,到后来的优化效率提升,优化成本降低。整体的优化进程总结下来: