共计 7861 个字符,预计需要花费 20 分钟才能阅读完成。
一、前言
挪动互联网人口红利见顶,用户增长放缓,挪动互联网各公司都在经验从服务好增量用户到服务好存量用户的思维转变,而低端机又是存量用户中重要的组成部分,因而低端机的性能优化变得尤为重要。
性能优化是最重要的优化体验的技术手段,重实践与实际相结合,技术挑战大,百度 App 性能团队也因而成立低端机专项攻克体验难题。本专题以低端机启动性能优化的视角,笼罩技术架构上的性能设计、性能问题定位、防劣化机制等方面最佳实际,最终造成性能优化闭环。
二、价值
以低端机为重点,辐射中高端机,通过技术和产品上的深度优化,可感知的晋升用户体验,实现扩充用户规模、晋升留存和晋升支出的指标。
三、难点
- 低端机性能问题简单:百度 App 启动流程简单,低端机启动过程中黑屏、卡顿等问题十分重大;
- 不足整体调度机制:波及业务泛滥,较多预加载工作,须要均衡研发性能和产品业务指标;
- 问题定位老本高:现有性能工具,无奈高效的发现、定位性能问题,归因剖析老本很高;
- 监控机制不欠缺:不足欠缺的防劣化机制,只能依附局部线上打点和用户反馈发现问题。
四、拆分
我的项目之初有几个灵魂拷问:
- 规范疑难:如何定义低端机?
- 联合百度 App 产品现状和手机配置散布,参考业界相干设计,自建低端机规范,采纳评分机制,保障评分主观和稳固,保障低端机占比的合理性;
- 主场景及指标疑难:如何开掘优化场景并形象指标,掂量低端机性能?
- 联合利用商店用户反馈、百度 App 反馈和论坛反馈,决定低端机优化主场景为点 icon 启动场景,次场景为端内查起场景,后续在利用全生命周期投入;
- 基于场景制订反映用户理论体验的性能指标,领导性能优化,量化性能工作;
- 提效疑难:如何疾速发现性能问题?
- 借助工具提效,自建稳固且高效性能工具基于目前已有工具二次开发,进步发现问题效率;
- 优化疑难:如何系统化的优化性能问题?
- 建设利用级的根底调度机制,服务于业务,并帮助业务优化性能;
- 开掘利用级的根底机制痛点,优化并降级根底机制,疾速晋升性能;
- 防劣化疑难:如何防止性能优化的同时呈现劣化问题,并打造劣化问题修复自运行的飞轮?
- 建设全研发流程的问题发现与定位的根底机制,简称版本防劣化;通过自动化测试和自助化文档服务,做到自动化测试、自动化剖析、自动化散发和自助化解决,建设指标的线上线下可观测体系。
基于上述疑难的了解,将低端机启动性能优化拆分为 3 个子方向,别离为 观测设施、基础设施和业务优化。
- 观测设施:建设低端机规范,建设启动性能掂量指标;建设线上、线下防劣化机制,实现线下随版的性能问题前置和线上问题的自动化剖析与归因;
- 基础设施:三驾马车,高效性能工具、高性能组件、调度框架。高效性能工具次要包含 Trace/Hook/TimeProfiler,服务于疾速发现并自动化性能问题;高性能组件次要优化手百根底性能并赋能业务,冲破零碎束缚与瓶颈,建设行业内当先的基础设施;调度机制作为优化的外围伎俩,业务初始化工作可通过接入调度器疾速实现性能优化;
- 业务优化:依据工具输入性能问题,协同业务优化不标准耗时、不合理“预”,初始化工作通过接入调度框架形式达到优化成果。
本文为低端机优化 - 启动优化我的项目的概述篇,整体形容下观测设施、基础设施和业务优化三个方面,后续会陆续公布性能工具 2 篇(Trace 工具 +Thor Hook 工具)、性能优化 1 篇、防劣化体系 1 篇。
4.1 观测设施
4.1.1 低端机规范
低端机定义,目前是依照机型评分 PV/UV 占比低于 15% 的评分定义为低端机,机型评分有:动态评分、动静评分和综合评分(动态评分和动静评分加权值)计划,目前线上百度 App 以动态评分为主,动静评分受经营等影响有稳定,业务可基于动静评分判断设施以后负载状况。基于 Android 和 iOS 机型散布差别,Android 以模型计算为主,iOS 以配置表为主。
动态评分
Android:机型品种繁多,无奈枚举,因而需通过手机的硬件配置信息(CPU/GPU/ 内存等),利用训练的数据模型,多维度计算给出一个综合评分,低端机占大盘比例 15%。
iOS:机型品种优先,可枚举,因而可通过配置表间接读取机型评分分数,低端机占大盘比例 15%。
动静评分
通过本地收集利用性能指标,目前实现了性能维度(启动速度为主)作为判断根据,线上收集大盘数据,并拟合生成启动工夫 - 性能评分,生成模型,通过传入性能指标参数,得出动静评分。
综合评分
依据动态得分和动静得分,依照权重计算,得出最终得分。
动态得分 * weight + 动静得分 * (1 – weight) = 设施最终得分启动性能指标。
4.1.2 启动性能指标建设
TTI (Time To Interactive),代表用户可输出的工夫。TTI 概念来源于 Web,先来看上面这张图:
图中波及几个要害名词,FCP (First Contentful Paint) 首次内容绘制,FID (First Input Delay) 首次输出提早,从图中图示可知 TTI 指标根本可代表主线程的晦涩水平。
Web 端 TTI 指标优劣评估如下,来源于 https://web.dev/interactive/。
基于 Web 端性能指标,联合挪动端现状形象 TTI 指标,掂量利用关上后,用户可输出的工夫,次要包含惯例启动 TTI 掂量点击 icon 进入手百性能,首次装置启动 TTI 用于掂量新用户首次装置启动利用的启动性能,在百度 App 上 TTI 终点为利用过程创立工夫戳,比拟靠近于点击桌面的工夫戳,完结点为主线程首次闲暇。
长久以来,开发者为了谋求更快的渲染速度而对页面进行优化,但有时,这会以就义 TTI 为代价。当用户尝试与看似具备交互性但实际上并非如此的页面进行交互时,用户可能会有如下两种反馈:
- 在最好的状况下,用户会因为页面响应迟缓而感到恼火。
- 在最坏的状况下,用户会认为页面已损坏,因而很可能间接来到,他们甚至可能对您的品牌价值丢失信念或信赖。
因而,为了防止这个问题,需尽所有致力将页面渲染实现工夫和 TTI 之间的差值降至最低。
4.1.3 防劣化机制建设
优化犹如防御,防劣化犹如防守,只有做到攻守兼备,能力持重优化。如何搭建防劣化机制,观测线下和线上的问题及指标状况,变得尤为重要。线下防劣化是第一环,及时发现劣化问题并晋升问题剖析效率,保障测试覆盖度,尽量笼罩用户的外围场景;线上防劣化则是在线下未发现问题并上线后,疾速发现并疾速定位线上问题。本文中会做简短论述,后续会有专文来论述这块内容。
线下防劣化
在代码主线分支(如 master 分支)或者研发同学开发分支,可提交防劣化工作自动化测试,目前百度 App 已实现 Daily 的自动化测试与散发,每个版本防劣化根本不须要投入人力,流水线主动散发,业务同学自助式解决问题。
Daily 测试中次要有如下几个步骤:
- 打包自动化:通过打包流水线和性能工具自动化脚本,实现流水线主动编译插桩、打包;
- 测试自动化:通过 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 高效性能工具
TraceView/CPU Profiler 性能损耗较大,原生 Systrace 无奈定位利用程序代码问题,随着优化逐步进入深水区,如何疾速定位和开掘问题,成为日常工作中急需解决的问题。百度 App 在我的项目中开发了两套工具,别离为 Trace 工具和 Hook 工具,Trace 工具以 ASM 插桩为根底,联合 Perfetto 相干能力,做到可视化和自动化剖析;Hook 工具以 Epic、Xhook 等 Hook 能力为根底,设计插件框架,实现插件级的 Hook 能力,反对热插拔,整体架构图如下:
通过工具的建设,Trace 工具可精确反映性能问题,剖析效率晋升显著,可发现锁、长耗时等问题,反对版本比照,为防劣化提供无力反对;Hook 工具齐备 Hook 能力,即用即插拔,可输入 I /O、线程等系列问题。在工具落地中,反对了低端机启动性能我的项目外,也反对了诸多我的项目的顺利落地。对于工具的细节可关注公众号后续发稿。
4.2.2 高性能组件
在低端机优化 - 启动性能优化中挖掘出诸多根底组件的性能问题,比方零碎原生组件性能差导致业务性能差问题,比方根底组件随着版本迭代或应用业务方逐步增多导致性能差问题,比方引入的第三方 SDK 导致的性能问题等,对诸多根底组件做了根底革新,如 Eventbus 事件库,Fresco 图片库、网络库等、也对系统相干机制做了优化,如 ContentProvider、FileProvider 等,本文中简略论述两个比拟有代表性的优化:SharedPreferences 优化和 ABTest 锁优化,在后续文章中会对优化项做具体论述。
SharedPreferences 优化
原生 SharedPreferences 有首次读取性能差、创立线程多、卡顿 /ANR,多过程反对差等毛病,从启动性能角度看 SP 加载时 wait 时长占比拟大,次要起因是该线程加载 SP 时,会新创建异步线程执行文件加载,此时该线程处于 wait 状态,直到文件加载实现后该线程才可继续执行,须对此种状况做针对性优化。
通过调研 Google DataStore、腾讯 MMKV、滴滴 Booster、头条等业界对 KV 存储做的相干优化,并参考其实现,最终在百度 App 中落地 UniKV,冲破零碎限度,彻底解决原生 SharedPreferences 有首次读取性能差、创立线程多、卡顿 /ANR、多过程反对差等毛病。
外围实现次要有:
- 高性能的数据迁徙框架,非阻塞式数据迁徙形式,业务无感知;
反对强类型存储,记录齐备数据,保障 getAll 接口可失常返回应用,思考到文件存储状态可能会发生变化,存储齐备数据保障数据再次迁徙的可行性;
- 对立接口层,默认实现为零碎 SP 实现,不影响业务中台,无学习老本,KV 优化和数据迁徙对业务通明,手百依赖 UniKV 实现层。
比照业界对 KV 存储做相干优化,均有不同水平劣势,目前在百度 App 大规模应用,接入文件 100+,优化线程数 100+,优化 TTI 约 1.2S。
锁优化
通过工具可看到锁相干信息,比方能够看到这段 Trace,具体如下图所示:
在我的项目中锁相干优化也是十分要害,以 ABTest 优化举例。从 Trace 文件中能够看到在 ABTest 模块中呈现了较多的锁信息,读取性能差,因而对 ABTest 模块进行了全面的摸底和剖析,ABTest 问题次要体现为:
- 通过 Trace 工具发现业务应用 ABTest 组件时呈现锁同步问题,耗时 200ms+;
- ABTest 组件因为历史起因,存在新老 AB 存储数据,导致首次读取耗时 2S+;
- 首次读取时易呈现 AB 值不精确问题,导致试验数据不可信。
针对上述几个问题,对 ABTest 做了重构,框架设计如下:
外围优化次要分为初始化优化和数据读取优化:
- 初始化优化:优化前读取新老 AB 全量数据,文件格式为 SP;优化后读取试验 id 和试验开关缓存文件,文件格式为 JSON/PB 格局,如果缓存文件不存在,则会读取原始数据保留数据。
- 数据读写:优化前 synchronized 整个内存缓存,读和写均有锁爱护,在高并发场景性能较差;优化后,读无锁,间接读取试验内存缓存,写无锁,因为写入无限次,在本次写入时通过内存级操作,在新申请的内存缓存中更新数据,更新全副数据后,将内存中的缓存地址更新为新申请的内存地址,解决锁带来的性能影响。
优化成果:
- 彻底解决业务应用 ABTest 组件锁同步问题,TTI 优化 200ms+;
- 兼容新老 AB 数据,且通过 JSON/PB 等数据格式验证,首次读取性能优化 95%(小米 5 机器);
- 解决 AB 试验数据准确性问题;
4.2.3 调度框架
百度 App 启动过程简单,波及业务泛滥,各预加载工作的执行诉求各有不同。在以往业务优化中,通过预加载、预链接、预渲染等各种“预”操作,对性能指标和产品体验做了相干优化,业务齐全优化掉耗时是比拟现实的状况,会有较多业务仍然保留“预”操作的诉求,因而须要建设一套调度框架,输入至业务方,业务可疾速接入,疾速解决优化业务的“预”操作带来的性能问题,达到启动性能和业务指标的均衡。本文中对此局部做简略论述,后续也会相干文章具体介绍此局部优化。
整体框架图如下:
调度框架的外围为智能调度,输出有两局部,次要是工作和信息采集:
- 工作:业务可将初始化、预加载工作封装成 Task,注册至工作管理器中,工作管理器可对工作进行辨认并示意,比方所属业务、依赖业务等,对工作执行状况做监控;
- 信息采集:次要包含机型画像(高 / 中 / 低端机)、行为画像(用户应用业务频次与时长)、场景辨认(闪屏场景、端内查起场景、发动搜寻场景等)、分级配置(不同机型画像不同的策略配置)。
输入为不同的调度状态,有个性化调度(不同用户运行时初始化不同业务)、分级体验调度(用户不同配置机型不同成果)、精细化调度(基于场景做调度)、分优先级延时调度(工作提早调度反对设置优先级,调整工作程序)和首页 UI 并行渲染技术(次要指商业闪屏和主页并行渲染),业务可依据预加载工作执行诉求疾速接入调度实现优化。在任务调度中,会为非凡业务做针对性调度,赋能业务,如闪屏和首页并行渲染,晋升商业申请成功率,进而商业支出。
4.3 业务优化
与业务协同,在技术和产品方面深度优化启动性能,次要流程如下:
- 问题发现:线下发现问题次要通过工具,如 Trace 工具发现主线程耗时重大问题,主线程锁期待问题等,Hook 工具发现主线程 I / O 问题,线程创立问题等;线上发现问题次要通过线上打点和试验防劣化机制;
- 问题协同:与业务沟通问题及技术计划,必要时帮助其剖析并优化,确认上线排期;
- 问题优化:次要由业务来实现具体优化,如果波及根底机制相干工作,则会由咱们来主导优化,在整个优化中,调度优化为次要优化形式,业务可疾速接入调度机制实现优化。
- 优化验证:及时跟进问题修复状况,在发版前回归问题,跟进线上优化成果,有些优化须要均衡业务指标和性能指标,如果优化不迭预期需持续协同优化。
五、总结
我的项目继续 1 年半,共经验了 3 个阶段:夯实根底阶段、防御冲破阶段、精密管控阶段。
第一个阶段:夯实根底阶段
- 建设低端机规范;
- 建设性能指标;
- 建设高效性能工具,提供发现问题的能力,发现突出矛盾,跟进解决;
- 建设根底调度机制,为后续业务接入做筹备;
第二个阶段:防御冲破阶段
- 通过性能工具开掘业务相干性能问题,与业务协同优化,并提供调度机制解决业务初始化与启动性能矛盾;
- 深度开掘底层组件性能优化性能;
- 联合外围业务场景,开掘业务价值;
第三个阶段:精密管控阶段
- 建设研发全流程的防劣化机制;
- 通过自动化测试和自助化服务,防劣化机制自运行,管制人力老本。
- 深度开掘业务场景,如目前在解决的开屏、内部调起等场景,搜寻、Feed 等外围场景须要浸透,须要在做调度机制降级相干工作;
低端机优化 - 启动性能优化我的项目实现了基础设施、监控设施和业务优化方向的建设,实现可感知的用户体验晋升,TTI 指标取得显著优化成果,惯例冷启动 TTI Androd 优化 50%+,iOS 优化 40%+,首次启动 TTI:Android 优化 40%+,iOS 优化 30%+。在我的项目中,踊跃与用户增长和商业的同学单干,也均获得不错的后果,百度 App 也将优化教训、根底机制、根底工具输入至矩阵产品,助力矩阵产品的性能晋升。
六、瞻望
启动性能是 APP 应用体验的门面,启动过程耗时较长很可能导致用户散失,启动场景作为资源竞争、卡顿情况严重的场景,各个公司团队均投入了较多精力来进行优化,且优化技术层出不穷,尽管百度 App 在此方向做了十分多的优化与尝试,但路漫漫其修远兮,百度 App 会继续深耕启动性能优化,为用户带来极致的启动体验。
与此同时,专一点不仅局限于启动场景,也会将更多精力投入到利用全生命周期、各 View 零碎的晦涩度建设与优化上,深刻优化用户体验。
——————————END——————————
参考资料:
[1] Web 指标 FID 链接:
https://web.dev/fid/
[2] Epic 链接:
https://github.com/tiann/epic
[3] xHook 链接:
https://github.com/iqiyi/xHook
[4] Perfetto 链接:
https://perfetto.dev/docs/
[5] MMKV 链接:
https://github.com/Tencent/MMKV
[6] Booster 链接:
https://github.com/didi/booster
举荐浏览:
面向大规模数据的云端治理,百度桑田存储产品解析
加强剖析在百度统计的实际
基于 TLS 1.3 的百度平安通信协议 bdtls 介绍
百度用户产品流批一体的实时数仓实际
如何治理资源节约?百度云原生老本优化最佳实际
面向大数据存算拆散场景的数据湖减速计划
百度 APP Android 包体积优化实际(三)资源优化