抖音 Android 性能优化系列:启动优化之理论和工具篇

sw
带着问题出发

假如你要负责优化抖音的启动性能,你会怎样去规划整体的优化方案?你可能会一下子想到很多方面的细节点,比如:要优化主线程耗时、要减少布局层级、要对某些启动任务做按需加载或预加载、要避免主线程IO、要对线程使用进行优化、还要有分析工具帮助定位性能问题等……

然而,该如何系统性地把这些细碎点组织起来并按照一定的章法来落地启动优化呢?此时,需要我们在具体细节点之上有进一步的问题分解与深入思考,最终形成一套完整的方法论,不仅能覆盖所有细节点,还能切实指导在实战中达成启动优化的效果。切实有效的方法论必然是从实战中经过千锤百炼才能形成的,而抖音庞大的用户基数又进一步保障了方法论的可行性与普适性。那么接下来让我们带着前述问题来看抖音的启动优化方法论是怎样的又是如何应用于实战之中的。

启动优化方法论

抖音的启动性能优化方法论分为五部分,分别是:理论分析、现状分析、启动性能优化、线上验证与防劣化。

这五部分间存在明显的先后顺序,又能闭环达成可持续的启动性能优化,下面将对这五部分做详细阐述:

理论分析

理论分析放在最先是为了从一开始就避免让视野受到限制,很多同学往往一开始接手启动优化就容易陷入对各种现状细节的分析,拘泥于片面的潜在可优化点,这样就难以做到对全局和优先级的把控,所以,我们应该首先跳出现状,从更加全局的视角来思考整体优化的目标和策略。这里可以利用特斯拉创始人——埃隆·马斯克所推崇的“第一性原理”思考法:

基于此,我们在做启动优化的理论分析时可以从更本源的角度出发做到全局思考,比如抖音会做从进程创建到页面展示的全启动路径分阶段耗时分析、还会按照消耗的系统资源类型做耗时成因分析,通过这种极致的耗时分析可以带来极致的优化策略,此外,从全路径出发还能够发现容易忽视的问题、探索优化的极限。

现状分析

在完成理论分析后,我们基本具备了全局的视角,并且也大致清楚了整体的优化目标和策略,接下来就要基于此来做现状分析从而明晰实现目标的具体路径:

首先使用profile工具对可优化点进行摸底:其实不合理的高耗时点就是潜在的优化点,并能按照前述的理论分析归入一个或多个耗时成因中;

然后结合线上的指标数据确定最终优化方向:线下摸底的潜在优化点要结合其线上打点确认是否为普遍耗时,再根据耗时成因明确大致的优化思路、实施成本和预估收益。

在这部分需要尤其注意三点:优质的profile工具(这里推荐使用同样来自基础技术团队的“btrace开源!基于Systrace高性能Trace工具”)、线下trace结合线上监控综合分析、根据投入产出比评估实施优先级,这三点是保障切实有效取得启动优化收益的关键。

启动优化

在完成了理论和现状分析后,就可以根据规划的路径来实施具体的启动优化项了。在实施过程中,主要考虑主线程优化、后台线程优化和全局优化三个维度:

主线程耗时优化需要在启动全路径各阶段中细化具体的耗时成因,如:CPUTime、CPUSchedule、IOwait、Lockwait等,完成耗时归因后可以使用逐步升级的优化策略来逐个击破:对于首屏所必须的耗时逻辑做正面优化(可使用缩减耗时逻辑、异步并发、延迟加载等手段)、对于非首屏必须的耗时逻辑做按需加载(需要架构优化的基础)、对于优化后仍存在耗时的逻辑尝试做业务降级(大都有损需评估全局收益);

后台线程优化策略与主线程类似,在此基础上还可以实施后台任务缩减、线程收敛、开启多进程等优化措施;此外,主线程和后台线程均存在较多启动任务且彼此间可能存在关联,因此,可以对全局的启动任务做依赖关系梳理并实施精细化的任务重排,旨在减少依赖任务间的等待耗时;

全局优化主要是指业务无关的通用的全局优化策略,如虚拟机层面或IO层面的优化等。

线上验证

在完成了具体的优化项施工后,就来到了线上验证大盘收益的阶段。这个阶段有三点需要注意:

在验证收益时通过AB实验达成,这样做不仅能控制变量确保优化项的严格有效,还能借此来观察性能优化所带来的业务指标收益,这些都可以作为规划后续启动优化方向的参考指导。

防劣化

在线上验证优化措施取得切实收益后,并不是万事大吉了,持续保持住优化效果才算完整达成了启动性能优化的目的。其实不仅是启动优化,整个性能优化领域都是围绕着“攻”和“守”来展开的,“攻”即为前述的分析与优化,而“守”则是防止劣化,在防劣化方面大家往往不会像优化的方面那么重视,但实际上能防止劣化是可持续取得优化效果的前提(否则新的优化效果会用于弥补劣化甚至入不敷出),并且防劣化相比于优化是更能持久有益的。

抖音启动性能防劣化的进程分为了三个时期,不同时期有不同的表现与应对手段,这很可能是大多数APP优化启动性能都要经历的,这里提炼出来以供参考:

快速下降期:此时一般位于启动优化的初始阶段,优化空间很大,伴随有小幅度的劣化但往往都能被更大幅度的优化抵消且还仍有收益,这时应该抓大放小,按照更高投入产出比的策略重点推进优化,同时也抽出少部分精力治理修复成本低的劣化。

瓶颈期:到了该时期绝大部分优化收益已经拿到,想进一步做到优化往往需要投入更多成本,且优化幅度有限,整体的投入产出比不高,同期还会伴随有中小幅的劣化,此时需要建立完善的线上线下监控体系,及时发现并修复劣化,此外还要通过架构改造从源头上限制劣化的发生,综合保障优化的收益不会被劣化抵消。

劣化期:这个时期往往出现在年关或重要节日期间,这类时间点往往有重要且紧急的活动项目上线,众多关联方面均要为其开绿灯,启动性能指标也不例外,为了保障活动效果可能要加入若干耗时的主线程启动任务,所带来的的劣化幅度往往比较大,此时需要对齐预期并在活动结束后及时修复。

启动优化方法论的应用实践

古人云“纸上得来终觉浅,绝知此事要躬行”,前述的方法论讲得再详细再透彻也会与实际的落地存在隔阂,为了做到真正的学以致用,下文将细致讲解如何将启动优化方法论应用于实践之中。

理论分析的实践

抖音在理论分析部分会对启动流程分别作全路径分析和耗时成因分析,前者用于发现全路径各个阶段的潜在耗时点避免疏漏,后者用于系统性地将各个耗时点归因从而引导我们找寻优化思路,关于这两部分的具体实践如下:

启动性能全路径分析:抖音的启动路径和大多数APP类似,整体分为两大阶段和两个间隙,它们按时间顺序排布为:Application阶段、handlemessage间隙、Activity阶段和数据加载间隙,全路径各部分细分涵盖的内容如下图所示:


APP进程由zygote进程fork出来后会执行ActivityThread的main方法,该方法最终触发执行bindApplication,这也是Application阶段的起点;然后是我们在应用中能触达到的attachBaseContext阶段,4.x的机型在该阶段具有较长的MultiDex耗时可以做针对性优化(可参考“开源|BoostMultiDex:挽救AndroidDalvik机型APP升级安装体验”),本阶段也是最早的预加载时机;接下来是installProvider阶段,很多三方sdk借助该时机来做初始化操作,很可能导致启动耗时的不可控情形,需要按具体case优化;此后就到了Application的onCreate阶段,这里有很多三方库和业务的初始化操作,是通过异步、按需、预加载等手段做优化的主要时机,它也是Application阶段的末尾。

在来到Activity阶段后,首先经历的是其onCreate生命周期,这里涵盖了首屏业务优化的主要场景也是开启异步并发的主要时机,在其中有个重要的setContentView方法会触发DecorView的install,可尝试对DecorView的构建进行预加载;后续自然来到View构建的阶段,该阶段在抖音上相当耗时,可采用异步Inflate配合X2C(编译期将xml布局转代码)并提升相应异步线程优先级的方法综合优化;再来到View的整体渲染阶段,涵盖measure、layout、draw三部分,这里可尝试从层级、布局、渲染上取得优化收益。

最后是首屏数据加载阶段,这部分涵盖非常多数据相关的操作,也需要综合性优化,可尝试预加载、缓存或网络优先级调度等手段。

此外,针对全路径所有阶段还可以实施通用性的优化项,如:启动任务调度框架、类重排、IO预加载、全局通用性框架优化等。

启动耗时成因分析:所有的耗时均因代码运行时不合理地消耗系统资源产生,而不合理的耗时点正是需要做归因分析之处。抖音按照不合理耗时点消耗的主要系统资源类型划分出五大成因,分别是:CPUTime、CPUSchedule、IOWait、LockWait和IPC,下面分别对各成因进行剖析:

CPUTime指占用CPU进行计算所花费的时间绝对值,中断、挂起、休眠等行为是不会增加CPUTime的,所以因CPUTime开销占比高导致的不合理耗时点往往是逻辑本身复杂冗长需要消耗较多cpu时间片才能处理完。比较常见的高CPU占用是循环,比如抖音启动时遇到过一个so加载耗时,最后定位原因是在解压so的时候,遍历ZipEntry的次数过多导致,一个可行的优化策略就是可以把so所在的ZipEntry提前,遍历完so的ZipEntry之后可以提前中止遍历,而不需要遍历剩下的无效ZipEntry。除循环之外,反射也是导致CPUTime的重要原因,像在序列化/反序列化、ViewInflate时,都有大量的反射操作,反射的耗时主要是字符串去查找Method或者Field,这个优化策略也可以考虑提前查找Method和Field缓存起来,或者是通过内联来降低Field数量等。另外一个常见的CPU耗时是类加载,类的加载过程包括:Load,从Dex文件里读取类的信息,可通过类重排优化;Verify,验证指令是否合法等,通过关掉ClassVerify可以优化该过程,同时高版本的vdex也是为了优化verify过程而设计,在dex2oat的时候做verify,verify之后的结果保存成vdex,后续只需要加载vdex;Link,给Field、Method分配内存,按照名字排序以方便后续反射的时候查找Field、Method等,这个过程的优化,art虚拟机采用了ImageSpace的方案进行了优化,将Link后的内存保存为image文件,后续可以直接load这个image文件,省去了Link过程;Init,类的初始化。

IOWait指发生了IO操作需要等待IO返回结果,这类耗时可能发生在读取资源和文件,类加载,甚至在内存不足时的PageFault都会导致IOWait。Resources的相关的操作耗时,主要是需要从apk里读取资源文件,优化策略可以有预加载、资源重排、资源异步加载等。类加载的IOWait和Resources类似,也可以通过类的重排、预加载等优化方案。文件读写导致的IOWait又分为业务文件和系统文件,业务文件指业务逻辑的读写文件,一般都可以通过异步来解决,而系统文件的例子是dex的读写,抖音的IOWait很大一块是它贡献的,目前的思路还是做dex的重排和IO的预读来尝试优化。

LockWait也是主要针对主线程,指其处于等锁状态,等待被其他线程唤醒或自己超时唤醒,导致这类耗时的问题种类多样,大体也是可以分为业务锁和系统锁,业务锁主要是被主线程等待的业务逻辑未能及时处理完,优化思路一般是移除主线程的锁等待逻辑或者加快被等待的业务逻辑的执行速度。系统锁主要有:StringInternTableLock,ClassLinkerLock,GCWaitLock等,目前抖音正在尝试优化这几类的锁耗时。

IPC指进程间通信,操作系统大都含有相应的机制,Android中所特有的IPC机制是Binder,由于进行IPC调用往往需要等待通信结果本质上这也算是一种LockWait,但Android特有Binder机制所以单独列出,这类耗时可采用减少或替代Binder调用等手段来优化。

综合前述的五大耗时成因,这里举一个分析启动阶段UI耗时成因的例子作为实践参考,根据UI界面的生命周期(一般划分)——UI构建、数据绑定、View显示三个阶段分别进行分析:

在UI构建阶段中首先要对界面布局的xml文件进行解析,这会导致IOWait耗时,在接下来要解析xml文件中的TagName从而获取对应View的class会用到反射、创建各子View实例并生成View树又会用到循环递归,两部分都会增加CPUTime的开销。

然后是数据绑定阶段,该阶段主要分两部分,一部分是对数据做请求、解析、适配,另一是部分是将适配好的数据填充进UI中,前一部分往往会涉及到Json解析成DataClass实例,这里就可能涉及反射、循环遍历嵌套的数据类结构等增加CPUTime的操作。

最后是View显示阶段,常见的measure、layout、draw三大渲染View的步骤就在其中,它们同样会产生递归遍历父子View的耗时,此外这里还涉及将应用层计算好的渲染View的数据传递给系统层做最终的像素点排布,那么必然又会产生IPC耗时。

从这个例子可见即使再复杂的场景只要我们进行细粒度的分析,都能将耗时点归入前述某一成因中。

现状分析的实践

如前文方法论所述,现状分析包括线下Profile数据与线上监控数据的对照分析,综合这两部分可以明确切实影响大盘启动性能的普遍耗时点,从而确保要做的优化项是行之有效的。下面分别讲述这两部分数据的分析实践:

线下Profile数据分析:Profile主要是指使用性能探测工具抓取应用启动路径各阶段的耗时和系统资源消耗情况,常见的开源Profile工具有TraceView、Systrace、AndroidProfiler等,这些工具各有优势但均不能完全满足抖音做线下Profile的需求(详见后文“启动性能优化工具”部分的讲解),为此,抖音自研了“新一代全能型性能分析工具RheaTrace”满足了需求。通过该工具我们可以在线下抓取整个启动路径的Trace文件,其整体样式与Systrace一致,但是涵盖了更多的信息点,一个样例Trace文件如下图所示:

线上监控数据分析:这部分数据的分析主要是用作参照和补充,参照是指线下Profile数据分析出的耗时点要对照线上数据确认其在大盘中存在普遍耗时,补充是指线下Profile数据未能复现的耗时点可能存在于线上大盘中,这部分漏掉的耗时点需要在线下尝试复现、归因后实施优化。这里有个很重要的点是:该如何对线上的启动性能指标做监控,这是保障线上数据能真实反映用户体验并且与QA(做竞品测试等)和业务方(判断业务需求是否影响启动性能等)达成一致的前提,下面将对这部分做详细阐述,分为启动性能指标的定义、统计和校准三部分:

启动性能指标定义:启动指标定义主要在于如何确定启动路径的起点与终点。起点的备选项有下图中的三个点以及Application的attachBaseContext方法:

接下来的是Framework中记录的APP进程创建起点,该API是AndroidN起才提供的兼容性较差;

再往后是Application的构造函数,按照Android官方生命周期式的开发模式通常不会往Application的构造函数中加逻辑,所以不建议在这里记录起点;

最后是大家熟悉的attachBaseContext方法也是Application生命周期中非常早的一个点,可以在这里记录启动点,虽然可能和真实情况有小幅差距,但能够起到基本的对照效应并且处于APP逻辑可以干预的范围内,抖音的启动路径起点选定的正是此处,此外也可以结合前述的内核中启动时刻综合观测。

而关于终点的定义同样有几个备选项:Activity-onResume、Activity-onWindowFocusChanged、View-dispatchDraw和DecorView-post:

dispatchDraw从View可见这个角度讲应该是比较接近用户感受的,但其受业务改动影响较大,不利于把控冷启时间及维护;

最后是通过DecorView在attachToWindow前post一个runnable来打点的方式,该方式可以保障在业务View完成渲染后做打点,但该方式可能会受业务同学做懒加载在打点前插入逻辑的影响,因此抖音的冷启终点也未选用该时机。

启动性能指标校准:由于启动路径往往比较复杂,因此添加了启动性能埋点后还需要额外的校准,总的原则是需要保障指标数据能切实反映大盘用户情形。在添加客户端埋点时最好是先梳理再分主路径和重点case分别打点,此外还要对若干异常case的数据进行剔除或分类避免污染打点数据,比如抖音在添加启动时间打点时就会对开屏广告、保活进程、push拉起、deeplink拉起、启动期间退后台、新用户启动等场景进行过滤或分开统计。

启动优化的实践

在做完理论分析与现状分析后,我们基本对全局待优化点及其大致优化方向会产生整体的认知,在开始落地各个优化措施之前还有很重要但往往会被忽略的一步——按优先级排布优化项、制定整体优化方案,这一步在很大程度上制约着后续启动优化的收益预期与进展把控,这两点对于按时达成启动优化的终极目标都至关重要。前述中提及了对“优先级”的把控,这点是制定整体优化方案的重中之重。

从抖音启动优化实践总结来看比较好的优先级策略是按照“投入产出比”来排布优化项,顾名思义:投入人力越少但优化幅度越大的优化项越应该排在前期,因为所有的性能优化历程都势必会经历从高收益到低收益的变化,那么相应的在排布优化项的前后顺序时也需顺应此规律,最终呈现的态势即为:前期以小成本快速降低大盘启动耗时,后期逐步提高投入突破各个瓶颈型耗时点(更后期大规模重构仅能减少几十毫秒启动时间的情形也应在预期之内),全过程同期加强防劣化机制,最终做到可持续优化。

在完成前述的全局优先级排布及方案制定后,才算真正来到了实施优化的阶段,在这个阶段所要用到的各类优化策略及配合方法在前文方法论部分已有详细讲述,在实战部分首先要补充一下前述几类优化策略按照“性能无损”、“业务无损”的区别划分,整体如上图所示,此外,我们会结合抖音启动优化实战经验列举各优化策略下可实施的优化项,以供参考:

按需优化:ContentProvider中过早初始化逻辑转为使用时初始化、多进程由启动时加载转为使用时或特定场景触发加载等;

延迟优化:4.x机型延迟执行中的Odex操作、主线程消息队列中非启动必要消息延迟执行、启动路径非高优业务逻辑延迟初始化等;

运行时优化:CPU提频、语言层面优化(内联、替换反射、避免用Kotlin的Range循环)、关闭VerifyClass、4.x机型抑制GC、主动触发AOT编译、资源重排、类重排、dex重排等;

异步优化:异步预加载(ShardPreference、实例化对象)、异步inflateview、线程收敛等;

降级优化:极速版、组件化降级、非必要耗时逻辑按人群/地区降级等;

综合优化:启动任务调度框架、启动路径重构、前后台启动任务精细化重排、后台负载优化等,这些优化项属于前述优化思想的综合应用,一般不局限于单方面的优化。

通过上述列举的各策略优化项你可能会发现,这其中有的优化项其实会对个别业务性能或功能有损,但最终对于启动性能是有显著提升的,那么此时需要按照“全局收益最大”的策略来综合评估这些优化项的可落地性,并不是只看单点的得失,这种全局性的思维在性能优化中非常重要。

线上验证的实践

这部分在前述的方法论中已针对三个关键点阐述得比较细致,这里仅针对三个关键点在落地时的技巧或注意事项加以补充:

在验证收益时通过AB实验达成:AB实验相对于观测不同版本的大盘数据来看更具有严谨性,因此在产出实验结论前同样需要保障数据量和时间跨度,抖音在开启性能的AB实验后,一般会让对照组及实验组进组用户各达到100万并保持至少5天后才进行实验的数据分析并产出结论,这样可以基本保障所有相关指标的稳定及置信。

防劣化的实践

防劣化的体系建设是个比较复杂的工程,要做好是有非常大的挑战的。抖音从最早的线下手动的分版本测试开始,经过了逐步的摸索优化,演变到当前涵盖了代码提交时静态检测、线下自动化劣化测试和归因、灰度劣化发现和归因、线上常态化的劣化监控和归因。防劣化是一个漏斗,从代码提交阶段到线下测试阶段,再到灰度发布阶段,再到线上版本发布阶段,我们希望劣化能够更前置的发现,每个环节都尽可能的发现解决更多的劣化,保证更少的劣化被带到线上。

防劣化是一个长期的工作,抖音投入已经有一年多了,目前整体效果还不错,在这个过程中也积累了比较多的经验,之后会专门写一个抖音的防劣化系列文章来给大家介绍我们的技术成果。

启动优化工具

古人云“工欲善其事必先利其器”,在启动性能优化领域也是一样,我们不仅需要趁手的工具来定位优化耗时问题,还需要尽量自动化的工具来持续发现劣化问题,也就是说整个启动优化在“攻”和“守”的两大方面均需要工具的辅助。那么下面将针对这两部分的工具分别进行介绍及分享抖音在启动优化工具方面的探索:

线下分析工具

这部分主要针对业界常见的APP性能探测工具进行基本原理解析及优缺点对比,具体包含的工具有:TraceView、CPUProfiler、Systrace,此外还将提及抖音自研的“抖音Android性能优化:新一代全能型性能分析工具Rhea”:

TraceView:Instrumentation模式下采用AddListener的方式注册MethodError、MethodExited、MethodUnwind的回调来采集方法起止时间;Sampling模式下使用一个SamplingThread定时主权线程堆栈,通过对此的堆栈对比近似确定函数的进入和退出时间;虽然是官方提供的工具,但两种模式本身都存在比较大的性能损耗,可能带偏优化方向;

CPUProfiler:整体通过JVMAgent实现,具有完成方法调用栈输出,且支持Java、C/C++方法的耗时检测,上手比较简单,但其同样存在性能损耗较大的问题,且一般仅用于debug包,release包需要额外添加debuggable的配置;

Systrace:基于Android系统层的Atrace实现,Atrace又基于Linuxkernal层的ftrace实现,ftrace在内核中通过函数插桩获取耗时;其自身性能损耗比较低、数据源丰富且具有较好的可视化页面,但其默认监控点较少,在APP自有代码中的监控点需要手动加入,比较麻烦;

RheaTrace:这是抖音基于字节码插桩结合Systrace及Atrace自研的工具,其具有自动加入监控点、各类耗时信息全面、性能损耗低等特点,是抖音日常在线下实施性能优化时首选的工具,其细节详见抖音Android性能优化:新一代全能型性能分析工具Rhea,这里不再赘述。

RheaTrace目前是抖音性能优化同学的主要工具,它不仅仅是一个工具,也是一个平台。除了Systrace自带的性能数据之外,我们增加了业务的函数耗时插桩的数据,可以更全面地对耗时进行分析。但是这些数据还不够,我们支持以插件的形式,增加自己定制的数据,比如为了优化IO的耗时,我们通过hook增加了更精细化的IO的信息,辅助定位IO的耗时问题;抖音的类加载耗时也是有些严重,我们也hook了类加载,增加了类加载的性能数据。我们要极致地优化抖音启动时间,以上这些数据是不够的,还有锁、View耗时信息等相关数据补充,给性能优化的同学提供全方位的性能分析工具。

除了RheaTrace之外,还有一些特定场景的小工具,比如线程分析工具、内存分析工具、高频函数分析等。由于篇幅有限,就不在这里一一介绍,后面会有专门的系列文章来介绍。

线上监控工具

上面介绍启动优化方法论的时候我们提到了,不能只是看线下的性能分析,线下的分析结果并不能完全代表线上大盘用户的情况。我们分析线上的性能数据,一方面能够验证我们的线上优化效果,另一方面能够从线上多个维度的数据里指导后续的优化方向。

线上监控工具和线下的差异点主要在低性能损耗和兼容性,我们将RheaTrace做了改造,使其能够满足线上的监控要求。性能损耗上,我们将监控的性能损耗控制在1%以内,包大小控制在200KB以内,基本实现了线上全量用户的启动耗时监控。通过启动路径的全量插桩,可以针对启动路径的各个阶段进行监控,一是可以发现线上用户哪些任务比较耗时,可以针对性的优化,让更多用户受益;二是可以监控线上的启动任务,如果发生了耗时增加,那么说明有劣化,这比监控到启动时间的劣化,要更容易定位到原因。除了线上的全量慢函数监控之外,我们的线上启动监控还会细化IO、锁、GC等多种维度的耗时数据,帮助定位线上为什么耗时慢,提供新的优化方向。

总结一下线上启动监控工具的思路就是:将线下的性能分析数据,低损耗的移植到线上,观察线上用户的性能数据,线上线下相结合的分析启动耗时,为启动优化提供优化方向指导。

启动性能优化之路去向何方

看了上文关于启动性能优化如此多的理论与实践,想必你已经意识到启动优化之路注定是不会平凡的,抖音在这条路上探索了2年之久且仍未到达尽头。在这条路上势必会经历前期的坦途、中期的迷茫与后期的瓶颈,但无论如何都要一直坚定地走下去,因为只要业务还有一天在迭代那么启动性能就有一天存在挑战的可能,所以启动优化之路的未来必然是无尽头的。

既然如此,那么我们的重点就应该从何时才能走完这条路转移到如何走得更精彩之上,甚至到最后能够做到把控这条路的走向,这或许也能算作另一种意义上的走完启动优化之路,那么什么才算走得更精彩以及把控路的走向呢?

迷茫时慢下步子再分析全局的耗时点寻找到新的优化策略、遇到瓶颈时先暂时放缓追赶指标尝试从代码重构上挖掘深层的收益、不断开拓跨领域(如端上智能降级)结合的优化方向……这些或许都能称作是一种精彩,并且会因人而异,最终,当这种精彩累计得足够多之时我们很可能会发现启动优化之路上已知的所有岔路口全被走了个遍,同期APP的启动性能也很可能已经达到了再优化也没什么明显业务收益的地步,并且出现的任何劣化点都能及时被解决掉,那么这时不出意外的话,启动优化之路走向的把控权已经尽在你手中了。

加入我们

抖音Android基础技术团队是一个深度追求极致的团队,我们专注于性能、架构、包大小、稳定性、基础库、编译构建等方向的深耕,保障超大规模团队的研发效率和数亿用户的使用体验。目前北京、上海、杭州、深圳都有大量人才需要,欢迎有志之士与我们共同建设亿级用户全球化APP!

文章版权声明:除非注明,否则均为纵投光影网原创文章,转载或复制请以超链接形式并注明出处。

上一个 徐静蕾促成《风犬》与张一白合作,中二风格有争议但改不了

下一个 深圳首个!古树保护与社区治理融合微改造项目在光明启用