百度App 低端机优化-启动性能优化(概述篇)
The following article is from 百度App技术 Author 龙少
一、前言
GEEK TALK
二、价值
三、难点
低端机性能问题复杂:百度App启动流程复杂,低端机启动过程中黑屏、卡顿等问题非常严重;
缺乏整体调度机制:涉及业务众多,较多预加载任务,需要平衡研发性能和产品业务指标;
问题定位成本高:现有性能工具,无法高效的发现、定位性能问题,归因分析成本很高;
监控机制不完善:缺乏完善的防劣化机制,只能依靠部分线上打点和用户反馈发现问题。
四、拆分
标准疑问:如何定义低端机?
结合百度App产品现状和手机配置分布,参考业界相关设计,自建低端机标准,采用评分机制,保障评分客观和稳定,保障低端机占比的合理性;
主场景及指标疑问:如何挖掘优化场景并抽象指标,衡量低端机性能?
结合应用商店用户反馈、百度App反馈和论坛反馈,决定低端机优化主场景为点icon启动场景,次场景为端外调起场景,后续在应用全生命周期投入;
基于场景制定反映用户实际体验的性能指标,指导性能优化,量化性能工作;
提效疑问:如何快速发现性能问题?
借助工具提效,自建稳定且高效性能工具基于目前已有工具二次开发,提高发现问题效率;
优化疑问:如何系统化的优化性能问题?
建设应用级的基础调度机制,服务于业务,并协助业务优化性能;
挖掘应用级的基础机制痛点,优化并升级基础机制,快速提升性能;
防劣化疑问:如何避免性能优化的同时出现劣化问题,并打造劣化问题修复自运转的飞轮?
建设全研发流程的问题发现与定位的基础机制,简称版本防劣化;通过自动化测试和自助化文档服务,做到自动化测试、自动化分析、自动化分发和自助化解决,建设指标的线上线下可观测体系。
观测设施:建设低端机标准,建设启动性能衡量指标;建设线上、线下防劣化机制,实现线下随版的性能问题前置和线上问题的自动化分析与归因;
基础设施:三驾马车,高效性能工具、高性能组件、调度框架。高效性能工具主要包括Trace/Hook/TimeProfiler,服务于快速发现并自动化性能问题;高性能组件主要优化手百基础性能并赋能业务,突破系统约束与瓶颈,建设行业内领先的基础设施;调度机制作为优化的核心手段,业务初始化任务可通过接入调度器快速实现性能优化;
业务优化:根据工具输出性能问题,协同业务优化不规范耗时、不合理“预”,初始化任务通过接入调度框架方式达到优化效果。
丨4.1 观测设施
丨4.1.1 低端机标准
静态评分
动态评分
综合评分
丨4.1.2 启动性能指标建设
在最好的情况下,用户会因为页面响应缓慢而感到恼火。
在最坏的情况下,用户会认为页面已损坏,因此很可能直接离开,他们甚至可能对您的品牌价值丧失信心或信任。
丨4.1.3 防劣化机制建设
线下防劣化
打包自动化:通过打包流水线和性能工具自动化脚本,实现流水线自动编译插桩、打包;
测试自动化:通过Docker镜像实现快速部署和迁移,通过Appium自动化测试框架,执行定制化case实现启动场景真机自动化测试;
分析自动化:通过脚本生成性能数据(Trace/Timeprofiler),脚本对比分析启动耗时、堆栈反混淆,产出劣化报表(或者svg图)的自动化;
分发自动化:通过脚本对劣化问题进行去重、置信度过滤,然后通过分发服务进行问题归属定位,分发;
线上防劣化
实验防劣化
函数级防劣化
函数级别打点报表观测能力建设:日常性能相关打点有sdk和业务调用两部分,较为普遍的实现方式为业务代码依赖打点sdk,接收打点数据后做数据上报,这种方式可以实现功能,但监控模块在中台输出组件时会是棘手问题,因此需要解除依赖。目前线下防劣化已实现自动化插桩,只是插桩逻辑为Trace.beginSection类似此种函数调用,业务无感知,因此解除依赖部分同样可以采用类似方式,但需要对插桩数据做控制, 否则包体积会出现较大增长。因此,基于配置文件的插桩,将打点sdk入口插入到需监控的业务方法中,即完成了与业务的解耦,也控制了包体积的增长。在确定解耦方案后,如何确定插桩函数List也是比较关键一环,关系到线上问题定位,在确定函数插桩列表时,需结合trace分析结果监控主线程长耗时任务和子线程核心任务,同时也需主动监控运营相关接口,保障数据波动时可归因。打点sdk中囊括维度主要有“函数调用耗时“和”函数开始执行时间戳“,在线上统计时会形成“函数执行PV维度”,线上报表可直观查阅3个维度相关信息。
自动化分析建设:通过“函数调用耗时“、”函数开始执行时间戳“和“函数执行PV”3个维度相关信息,基本可实现线上问题的自动化分析与归因,整体逻辑为:在自动化分析中,首先通过函数开始时间戳维度可以诊断出哪些业务执行开始时间变慢,在日常问题定位中,极有可能会出现监控函数耗时无法明确诊断出问题,主要原因为函数级别监控为有限个函数统计,此部分监控会与主观认知相关,此时可借助函数开始时间戳维度和函数打点的PV维度,来看哪部分执行PV或者执行时间戳变慢。总体流程如下图:
丨4.2 基础设施
丨4.2.1 高效性能工具
丨4.2.2 高性能组件
SharedPreferences优化
高性能的数据迁移框架,非阻塞式数据迁移方式,业务无感知;
支持强类型存储,记录完备数据,保障getAll接口可正常返回使用,考虑到文件存储形态可能会发生变化,存储完备数据保障数据再次迁移的可行性;
统一接口层,默认实现为系统SP实现,不影响业务中台,无学习成本,KV优化和数据迁移对业务透明,手百依赖UniKV实现层。
锁优化
通过Trace工具发现业务使用ABTest组件时出现锁同步问题,耗时200ms+;
ABTest组件由于历史原因,存在新老AB存储数据,导致首次读取耗时2S+;
首次读取时易出现AB值不准确问题,导致实验数据不可信。
初始化优化:优化前读取新老AB全量数据,文件格式为SP;优化后读取实验id和实验开关缓存文件,文件格式为JSON/PB格式,如果缓存文件不存在,则会读取原始数据保存数据。
数据读写:优化前synchronized 整个内存缓存,读和写均有锁保护,在高并发场景性能较差;优化后,读无锁,直接读取实验内存缓存,写无锁,由于写入有限次,在本次写入时通过内存级操作,在新申请的内存缓存中更新数据,更新全部数据后,将内存中的缓存地址更新为新申请的内存地址,解决锁带来的性能影响。
彻底解决业务使用ABTest组件锁同步问题,TTI优化200ms+;
兼容新老AB数据,且通过JSON/PB等数据格式验证,首次读取性能优化95%(小米5机器);
解决AB实验数据准确性问题;
丨4.2.3 调度框架
任务:业务可将初始化、预加载任务封装成Task,注册至任务管理器中,任务管理器可对任务进行识别并表示,比如所属业务、依赖业务等,对任务执行情况做监控;
信息采集:主要包括机型画像(高/中/低端机)、行为画像(用户使用业务频次与时长)、场景识别(闪屏场景、端外调起场景、发起搜索场景等)、分级配置(不同机型画像不同的策略配置)。
丨4.3 业务优化
问题发现:线下发现问题主要通过工具,如Trace工具发现主线程耗时严重问题,主线程锁等待问题等,Hook工具发现主线程I/O问题,线程创建问题等;线上发现问题主要通过线上打点和实验防劣化机制;
问题协同:与业务沟通问题及技术方案,必要时协助其分析并优化,确认上线排期;
问题优化:主要由业务来完成具体优化,如果涉及基础机制相关工作,则会由我们来主导优化,在整个优化中,调度优化为主要优化方式,业务可快速接入调度机制实现优化。
优化验证:及时跟进问题修复情况,在发版前回归问题,跟进线上优化效果,有些优化需要平衡业务指标和性能指标,如果优化不及预期需继续协同优化。
五、总结
建设低端机标准;
建设性能指标;
建设高效性能工具,提供发现问题的能力,发现突出矛盾,跟进解决;
建设基础调度机制,为后续业务接入做准备;
通过性能工具挖掘业务相关性能问题,与业务协同优化,并提供调度机制解决业务初始化与启动性能矛盾;
深度挖掘底层组件性能优化性能;
结合核心业务场景,挖掘业务价值;
建设研发全流程的防劣化机制;
通过自动化测试和自助化服务,防劣化机制自运转,控制人力成本。
深度挖掘业务场景,如目前在解决的开屏、外部调起等场景,搜索、Feed等核心场景需要渗透,需要在做调度机制升级相关工作;
六、展望
END