3倍+提升,高德地图极致性能优化之路

简介: 伴随着高德地图APP近几年的高速发展,也面临到这些问题,从2019年开始,我们开启了一系列性能优化专项,对高德地图APP进行了深入性能分析和极致优化,取得比较显著的效果。在这个过程中总结了一系列优化思路和技术方案,希望对同样面临超级应用性能问题的你有所帮助。

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.总结与思考

决心大于方案

超级应用的性能问题往往关联多方业务,需要多方团队协作,所以自上而下对性能的重视程度和优化决心是决定成败的关键,打通任督二脉,才能事半功倍,把优化方案顺利落地。

攻城难,守城更难

业务与技术都在快速迭代,要想保证优化成果防止反弹,管控是必须的,而管控就会有束缚和效率影响,管控过程中就难免会遇到各种各样的阻力。所以一方面技术上,建立标准规则,配合提效工具和优化流程,尽量避免影响业务开发。另一方面,团队需要具有共同认知,性能体验与功能体验同等重要,用户对比心智很强,性能体验往往与产品口碑直接挂钩。

性能优化永远在路上

目前,我们很多优化策略以及数据参数还是从实验室调校而来。未来,我们会进一步探索云端一体、端智能等技术,做到更懂用户,贴合业务和用户特点,实现性能体验的个性化提升。

相关文章
|
6月前
|
缓存 前端开发 JavaScript
如何优化前端性能提升用户体验
在Web应用中,前端性能是影响用户体验和转化率的关键因素之一。本文将介绍一些优化前端性能的方法,包括减少HTTP请求、使用缓存、压缩代码等。
|
4月前
|
监控 Java 图形学
【性能优化篇】U3D游戏卡顿大作战:内存与渲染效率的极致提升
【7月更文第12天】在Unity3D游戏开发领域,性能优化是决定玩家体验好坏的关键一环。游戏频繁卡顿,不仅破坏了沉浸式体验,还可能造成玩家流失。本文将深入探讨如何有效解决U3D游戏卡顿问题,特别聚焦于内存管理和渲染效率两大核心领域,助力开发者打造流畅丝滑的游戏世界。
294 0
|
缓存 算法 大数据
倚天710规模化应用 - 性能优化 - 软件预取分析与优化实践
软件预取技术是编程者结合数据结构和算法知识,将访问内存的指令提前插入到程序,以此获得内存访取的最佳性能。然而,为了获取性能收益,预取数据与load加载数据,比依据指令时延调用减小cachemiss的收益更大。
|
6月前
|
缓存 前端开发 UED
实战指南:如何优化前端性能提升用户体验
本文探讨了在当今互联网时代,前端性能优化对于提升用户体验的重要性,以及如何利用各种技术手段实现前端性能的优化。通过介绍前端性能优化的原则、常见的性能优化技巧和工具,以及实际案例分析,帮助开发者深入了解并掌握提升前端性能的方法,从而提升网站的加载速度、响应速度,提高用户的满意度和留存率。
|
6月前
|
搜索推荐 数据挖掘 Android开发
数据驱动性能体验优化
数据驱动性能体验优化
156 0
|
数据采集 算法 编译器
倚天710规模化应用 - 性能优化 -自动反馈优化分析与实践
编译器优化分成静态优化与动态优化,静态优化指传统编译器gcc/llvm时,增加的优化等级,如O1,O2,O3,Ofast,此时,编译器会依据编译优化等级增加一些优化算法,如函数inline、循环展开以及分支静态预测等等。一般情况下,优化等级越高,编译器做的优化越多,性能会更会好。在阿里生产环境中,单纯依赖于静态优化,并不能达到程序运行流畅目的,通过分析CPU硬件取指令、执行指令,往往会出现一些分支预测失败导致iCacheMiss率高的场景,限制了程序的性能进一步提升。基于此,业务引入了动态反馈优化工具,依据生产环境的实际运行数据,反哺指导编译器对程序代码进一步调整编译优化策略,提高分支预准确率
|
边缘计算 缓存 Kubernetes
OpenYurt v1.2 亮点速览丨云边流量峰值相比原生 K8s 降低 90%
北京时间 1 月 30 号发布的 OpenYurt v1.2.0 版本,社区呼声最高的几大特性终于落地,OpenYurt 的特点更加鲜明,主要特点包括:Kubernetes 无侵入,云边端全协同,可编程的资源访问控制,以及声明式云原生设备管理。
OpenYurt v1.2 亮点速览丨云边流量峰值相比原生 K8s 降低 90%
|
Dubbo 算法 NoSQL
记一次提升18倍的性能优化
最近负责的一个自研的 Dubbo 注册中心经常收到 CPU 使用率的告警,于是进行了一波优化,效果还不错,于是打算分享下思考、优化过程,希望对大家有一些帮助。 自研 Dubbo 注册中心是个什么东西,我画个简图大家稍微感受一下就好,看不懂也没关系,不影响后续的理解。
253 0
记一次提升18倍的性能优化
|
机器学习/深度学习 存储 人工智能
数量级效率优势,原生适配AI计算:光芯片的下一个技术突破要来了
数量级效率优势,原生适配AI计算:光芯片的下一个技术突破要来了
310 0
数量级效率优势,原生适配AI计算:光芯片的下一个技术突破要来了
|
Dubbo 算法 NoSQL
记一次提升18倍的性能优化!
最近负责的一个自研的 Dubbo 注册中心经常收到 CPU 使用率的告警,于是进行了一波优化,效果还不错,于是打算分享下思考、优化过程,希望对大家有一些帮助。自研 Dubbo 注册中心是个什么东西,我画个简图大家稍微感受一下就好,看不懂也没关系,不影响后续的理解。Consumer 和 Provider 的服务发现请求(注册、注销、订阅)都发给 Agent,由它全权代理Registry 和 Agent 保持 Grpc 长链接,长链接的目的主要是 Provider 方有变更时,能及时推送给相应的 Consumer。为了保证数据的正确性,做了推拉结合的机制,Agent 会每隔一段时间去 Regist