EN

Android App 启动优化全记录

字数统计: 7k阅读时长: 24 min
2019/11/18
loading

本文参考了目前大部分 Android 应用启动优化的方案,将大家的方案做一个汇总,如果你有这方面的需求,只需要对照这篇文章,看看其他人的方案,查漏补缺。很多方案是要根据具体的业务去做优化的,所以这里也没有对每一种方案进行详细的介绍,要用到哪一个方案的时候,可以具体去网上查找对应方案的具体实现方法,这里只是做一个汇总

另外我还加上了部分系统厂商所做的启动相关的优化,不过只写了一些我知道的,还有一些厂商有黑科技,就不在这里的讨论范围了。知道厂商做的事情,可能也会帮助到你,比如联系厂商做白名单、接入厂商 SDK 等

版本说明(2026-10-13 核查):本文原发于 2019 年,保留当年的案例和优化分类。冷、温、热启动、测量指标与系统启动页已按新版文档补充;厂商白名单、预测和重启策略仅作历史线索,不能当作所有设备共有的能力。Android 10 / 16 的进程池与调度相关说明以版本化源码为准。

现在做启动优化,先固定“何时算启动完成”:首帧、首屏内容和可交互并不相同。用 Macrobenchmark 重复测量关键入口,结合 Perfetto 查主线程、RenderThread、Binder、I/O 和 GC;线上再按设备与版本观察启动分布及稳定性。Baseline Profiles 用于指导 ART 编译,Startup Profiles 用于构建时的 DEX 布局,两者不能混为同一种编译优化。

应用启动概述

应用启动的一般流程

从桌面点击图标到主界面可操作,会经过系统调度、必要的进程/组件初始化、UI 构建与内容加载。下面是旧版简图,只画出了部分阶段:

  • SystemServer 协调进程启动、Activity 与窗口管理;需要普通 App 进程时会请求 Zygote 派生或使用可用的 USAP,并不是由 SystemServer 自己直接 fork App。
  • App 进程 在主 Looper 已建立后处理应用绑定、Provider 初始化、Application.onCreate() 和 Activity 等工作。不是每次启动都要创建四大组件;Service、Receiver 等取决于入口与业务。

图中把 Application.onCreate 画在 MainThread 框外,不能据此理解成它运行在其他线程,或执行完它才创建主线程。首帧画出之后,网络内容和可交互状态也可能仍未准备好。

冷启动和热启动

还需要补上原文遗漏的 温启动。按常见进程/Activity 状态理解:

  • 冷启动(cold):需要启动 App 进程,执行应用与界面的初始化。
  • 温启动(warm):典型情况是进程仍在,但目标 Activity 需要重新创建,执行 onCreate() 等流程。
  • 热启动(hot):已有 Activity 实例及界面状态可复用,主要是恢复到前台;仍可能有恢复内容、布局或绘制工作。

Back、Home 不是可靠的分类开关:Activity 的状态和版本行为可能不同,后台进程也可能已被回收。最近任务列表里的卡片更不能证明进程仍存活。测量时记录进程是否重建、Activity 是否重建,并以工具对 cold / warm / hot 的定义为准。参见 启动状态说明。

启动速度的测量

各家应该都有自己的方案,关键在于如何定义启动结束的点,这也是一直困扰我的一个地方。复杂页面需要明确可观察的结束条件,不能只选一个看起来更小的数字。

  • TTID:目标页面首帧显示的时间,系统可以观测;首帧可能还只是骨架或加载状态。
  • TTFD:App 在主要内容就绪后通过 reportFullyDrawn() 或相应的 ReportDrawn API 报告。它取决于业务定义与上报时机,不会自动证明所有交互都正确。
  • 可交互/业务完成:例如列表能点击、登录完成,需要另外定义场景和断言。OCR 能辅助识别目标内容,但文字出现不保证图片加载完成或按钮已可操作。

Macrobenchmark 的 StartupTimingMetric 提供 timeToInitialDisplayMs 和 timeToFullDisplayMs;后者关联 fully-drawn 信号所在或之后的相应渲染帧,不能把没有上报的结果填成 0。固定 release 构建、启动模式、编译/Profile 状态、登录与数据状态,在真实设备重复采样,比较分布,同时保留 Trace。基准工程配置见 Macrobenchmark 指南。

adb shell am start -W 仍适合快速诊断,但输出字段有版本差异:旧版常见 ThisTime/TotalTime/WaitTime;AOSP Android 16 输出 LaunchState、TotalTime、WaitTime,不再输出 ThisTime。WaitTime 也不是首屏内容或纯 App CPU 时间。一次命令或一次录屏都不能替代稳定的发布基准。

原文参考的 手淘全链路性能优化 提倡自动化、稳定和持续集成,并用 OCR 识别页面。这里保留方法线索,不把其 OCR 服务识别率当成当前 App 启动终点识别的准确率。

App 优化

启动窗口优化

系统 StartingWindow、Android 12 的 SplashScreen,以及 App 自己的 SplashActivity 是不同的东西。启动页能改善等待反馈,但不能替代实际初始化优化。

  • 对旧版主题预览窗口,避免无必要地用 android:windowDisablePreview="true" 造成无内容等待;主题背景尽量与进入后的界面一致。
  • Android 12(API 31)起,系统在冷/温启动使用标准 SplashScreen。按 官方迁移指南 配置主题与 API;旧背景大图和禁用预览的技巧不能当作新版通用方案。保留额外 SplashActivity 还可能导致连续两次闪屏。
  • 能直接路由到目标 Activity 时减少无意义的中转。登录、深链和广告有业务约束,应分别测量,不要为了“只有一次跳转”破坏状态恢复。

原文提到微信、知乎、抖音的配置属于当时观察,缺少可复核的版本与白名单证据,不能据此断言这些应用现在如何配置或很少冷启动。

线程优化

线程优化要控制同时运行的工作与依赖等待。可运行线程过多可能增加主线程的 Runnable 等待;Sleep 则还可能来自锁、条件变量、Binder 或正常空闲,不能全部归因于 CPU 不够。

  • 按任务类型限制线程池并发与队列积压,线程池本身不会自动消除过载。
  • 查明主线程等待的锁及持有者,避免把依赖迁到后台后又立即在主线程等待结果。
  • 按依赖组织初始化,区分主线程专属与可并行工作。原文中的 mmkernel、Alpha 是历史架构参考,不是必须接入的标准组件。

系统调度优化

启动时要减少关键路径上的无必要工作:

  • 合并重复的同步 Binder 查询,并跟踪 AMS/ATMS、WMS 的锁等待。Binder 调用不等于所有“系统调用”,调用多也不必然意味着都争同一把锁。
  • 延后首屏不需要的额外进程;多进程会增加初始化与竞争,但负担不是简单“翻倍”。有隔离要求的进程不能随意合并。
  • 留意 Provider、Service 等初始化占用各自进程主线程的时间,尤其是先于 Application.onCreate() 的 Provider 初始化;远程 Provider 请求和 Service Binder 方法又可能在 Binder 线程池执行。
  • 对可异步的工作安排后台执行,并明确首屏是否依赖其结果。必需且限主线程的工作仍要缩短,不能盲目挪线程。

下面的旧 CPU 图能看到多种工作交错,不能只凭颜色断言 CPU 饱和或某个 App 是唯一原因:

SystemServer 图可见 monitor contention 及锁持有线程,所选窗口为 93.633 ms;这是观察区间,不是所有锁等待之和,也不是整个启动耗时。应顺着持有者继续查:

GC 优化

减少启动路径上的不必要分配,并结合分配量、GC pause 和主线程等待判断收益,不能只数 GC 次数。

  • 避免重复生成大字符串、反复序列化和一次性解析首屏不需要的内容。
  • 对象复用需要有清晰的所有权和大小上限;对象池可能增加常驻内存或锁竞争。
  • Native 分配仍占进程内存,还带来 JNI、生命周期和泄漏风险。不能把“搬到 Native”当成消除内存成本的通用优化。

原案例:支付宝客户端启动速度优化之垃圾回收。

IO 优化

启动中,文件读取、缺页、解压、数据库和其他进程的 I/O 可能相互影响。先记录文件、实际读写字节数、调用次数、线程和持续时间,再区分 CPU 解析与等待;不要用文件总大小代替本次读写量。

首屏必需的网络请求可以异步发起,非必需请求延后;“启动时完全不做网络 I/O”不适用于依赖在线内容的页面。磁盘访问也要尽量移出主线程,并避免主线程随后同步等待。

这张表是原文的观测维度示例:chat.db 文件 500 MB、此次写入 800 KB 是不同字段;表里的 KB/MB 标记未说明十进制还是二进制,不能据此推算精确吞吐率。各行耗时和 Buffer 大小不是推荐配置。

上面两张图分别涉及系统录屏进程和另一个 App,不是同一进程的受控对照。线程状态轨道里的 I/O 等待要看选中状态、阻塞栈和相关事件,不能把橘红色函数片段一概解释成 I/O,也不能只凭局部图证明低内存是根因。

资源重排

原方案通过调整 APK 内资源排列,尝试改善启动读取的局部性,利用 page cache 和预读减少缺页及小块读取。可参考当时的 支付宝安装包重排布案例。

Page cache 缓存文件内容,常规 buffered I/O 和文件映射会用到它;预读是否有效,取决于访问模式与缓存状态。文件内偏移相邻不保证物理存储连续;页大小、文件系统块大小、APK 压缩和映射方式也不能混为一谈。

图上标的是 Linux 4.0(2015)的存储栈,只作历史示意,不代表当前 Android 完整实现。现代构建要考虑 split APK、压缩、对齐和签名;重排必须在构建签名流程内完成并验证产物。缓存已热时收益可能很小,要用相同设备与缓存条件做 A/B,而不是默认“一重排就减少磁盘 I/O”。

类重排

ReDex 的 InterDex 可以根据启动类清单改善 DEX 布局;参见 项目文档。实际还要满足 DEX 容量、主 DEX 约束和后续优化,不能概括成“不分析任何约束,把所有启动类塞进主 dex 即可”,收益也需要同场景 A/B。

新项目可评估 Startup Profiles。 它在构建阶段改善 DEX 中启动代码的局部性;Baseline Profiles 则向 ART 提供关键代码路径用于编译,两者用途不同。按 Startup Profiles 配置文档,DEX layout optimization 从 AGP 8.1 提供、8.3 起默认开启;8.1–8.2 需显式启用,并按文档配置 R8。推荐工具组合为 Macrobenchmark 1.2.0+、AGP 8.2+。生成规则后还要确认 release 产物实际消费,并测试桌面、深链等入口,不套用别家提升百分比。

主页面布局优化

应用主界面布局优化要结合实际 Measure、Layout、Draw 或 Compose 的构建与布局耗时:

  • 减少冗余层级和重复测量;层级数量不是唯一性能指标。
  • 用 ViewStub 延后暂不需要的 View,但注意首次展开的延迟,不要把卡顿集中到第一次点击。
  • 自定义 View 可减少某些叠加成本,同时需要维护交互、无障碍和绘制逻辑;不能保证一定比标准控件快。

闲时调用

IdleHandler 属于 MessageQueue,在所属 Looper 的队列满足空闲条件时执行,不是“某个 Handler 空闲”。返回 true 表示保留以便以后的空闲时机再回调,返回 false 表示移除;true 不表示立即无限循环。

回调仍在这个 Looper 的线程上运行。主队列的 IdleHandler 不适合直接做网络请求、重 I/O 或大量 View 构建;它既不保证何时触发,也不会自动把任务移到后台。可用它轻量安排非必需工作,但不能让首屏必需任务无限等空闲。合同与实现见 IdleHandler 和 Android 10 MessageQueue。

类加载优化

Trace 中的 VerifyClass 可以提示类校验工作,但它的墙钟区间也可能含调度等待;并非每次启动都会重新校验所有方法。要结合实际 ART 版本、编译状态与加载路径分析。

这张带有 dexopt、VERIFY_MODE_NONE 的图是旧运行时示意,不能作为现代 App 关闭 ART 校验的做法。Android 7 起 ART 使用解释、JIT 与 AOT 的组合,具体产物和策略随版本变化,见 ART 配置说明。App 侧优先减少无用初始化,并正确生成、打包和验证 Baseline Profiles;Profile 已打包不等于该次设备启动已经完成预编译。

App 瘦身

包体、安装占用、解码内存和启动耗时是不同指标,要分别看:

  • 用 Android Lint / IDE inspections 找无用代码与资源,再确认反射、JNI、动态资源访问等保留规则。
  • 在 release 构建中配置 R8 与资源收缩。缩短符号名的混淆与删除无用内容的 shrinking 不是一回事。
  • RGB_565 是每像素 2 字节、无 alpha 的 Bitmap 内存配置,不是替换 PNG/JPEG 的 APK 文件格式。是否适用要看透明度、色彩和解码行为;压缩格式与解码尺寸另行选择。
  • 资源重命名或减少 DEX 文件数不保证更快。应检查真实包体和启动路径,避免破坏资源查找或为了数量更少而引入额外启动工作。

选择合适的启动框架

先把初始化任务及其依赖画成有向无环图(DAG),再决定阶段、线程和并发上限。图描述的是先后约束,本身既不要求多进程,也不会自动让任务并行或解决拥塞。对必需依赖明确完成/失败状态,不要把“已提交后台任务”当成初始化完成。

下面三张是原手淘案例的阶段划分,包括基础库、页面依赖、可选预加载和按需初始化。m-a、m-f-a、m-b-f、m-idle 是案例自己的标记,不是 Android 生命周期;图里的“一定执行”也不能作为任意 IdleHandler 的保证。

当前可用 Jetpack App Startup 声明 Initializer.dependencies(),将多项自动初始化集中到一个 Provider。它按依赖同步调用 create(),不是自动并发的启动调度器;默认自动初始化通常发生在主线程、Application.onCreate() 之前。若改为手动/懒加载,要检查合并后的 manifest 以及其他 initializer 是否仍依赖它,防止提早初始化或漏初始化。

历史案例:手淘全链路性能优化。

启动网络链路优化

下面整理的是原手淘案例里的问题类别;库名、线程名和耗时来自旧案例,不是所有 App 的默认行为。

问题和优化点

  • 发送阶段:某些库初始化或 bindService 阻塞请求,图片任务在限流队列中等待。
  • 传输阶段:首屏不需要的资源或过大响应占用链路。
  • 解析阶段:复杂 JSON、解码或回调长期占用有限工作线程。
  • 上屏阶段:结果虽已返回,主线程排队或重回调仍延迟显示。

原文的“解析 3 s、高端机 1 s、低端机 3 s 以上”属于案例描述,缺少可复现实验条件,不能当设备档位的通用阈值。

优化

  • 合并重复请求,延后首屏不需要的数据;请求去重不等于盲目把所有网络连接合成一个。
  • 限制下载、解析和图片解码并发,防止为了网络快把 CPU、内存或回调队列压满。
  • 在合适的工作线程解析,主线程只应用必要结果,并处理取消和过期回调。
  • 60 / 90 / 120 Hz 的刷新间隔约为 16.67 / 11.11 / 8.33 ms。一个回调不能独占整个间隔,低于 16 ms 也不保证帧不超时,应按实际帧 deadline 和整体主线程工作判断。

预加载

如果能在用户导航前获知需求,可以提前异步准备数据,让页面就绪后复用结果。要处理取消、错误、账号切换、缓存过期和内存上限;没有提前执行的时间窗口时,只是把工作搬到别处,并不必然缩短端到端等待。

原文的 PreLoader 项目 保留为历史实现参考,接入前应检查维护状态与当前项目兼容性。

保活

进程保留可以省去部分下次启动的工作,但 Activity 已销毁时仍可能是温启动,不能把“进程没死”直接等同于热启动,更不应该以常驻进程替代冷启动优化。

这里说的保活,并不是建议大家用相互唤醒、通知轰炸等手段,而是提供用户需要的功能,合理释放后台资源,停止不必要的服务和动画。

说起来是这个方向,但我也知道,对 App 开发者而言,上面的做法有些理想化:自己已经尽量释放资源,应用到了后台,仍可能被厂商策略处理掉。Android 的生态需要应用开发者和系统厂商一起改善。后台限制、用户设置和厂商策略都有版本差异;厂商白名单属于具体合作安排,不是做好内存优化就能获得的标准承诺。App 仍应能在进程被回收后正确恢复,也不能假定一定收到低内存回调才会被杀。

业务梳理

这里涉及具体业务,每个 App 都不一样,但可以逐项确认启动模块是否必需、依赖谁、可在哪个线程执行。下面仍沿用原案例的四个维度:

  • 必要且耗时:先缩小工作量,再把允许离开主线程的部分异步化;首屏依赖的结果必须有明确就绪条件。
  • 必要且不耗时:放在合适的初始化阶段,不因“很快”忽略累积成本。
  • 非必要但耗时:延后、按需或取消,避免首帧之后所有任务同时爆发。
  • 非必要且不耗时:不在启动时执行,需要时再加载;不等于删除仍有业务用途的功能。

图中的分步、异步、延期是三种手段,不是把每个耗时任务搬线程就算完成优化。

业务优化

  1. 先定位明显瓶颈,减少重复与无用工作,再检查改善是否影响其他入口。
  2. 结合当前需求偿还技术债,重构范围围绕已证实的启动问题。

原文引用的 业务优化案例 可以作为排查清单,但其中有两点需要纠正:

  • THREAD_PRIORITY_BACKGROUND = 10 是 Android 的线程优先级常量,不是“最多获取 10% CPU 时间片”。CPU 份额受调度组、其他可运行任务和设备策略影响;主线程依赖的关键任务也不宜无判断地降优先级。见 Process 文档。
  • 多进程 App 的各进程都有自己的 Application 生命周期。应按进程限制具体 SDK/业务初始化,而不是声称系统只在主进程调用 Application.onCreate();子进程自己的必要初始化不能跳过。

其余可迁移的思路是:延后更新与统计等非首屏工作;移除无用旧代码、调试代码、重复逻辑和 SDK Demo 残留;控制线程池总并发;缓存重复查询但定义失效和账号边界。数据库/I/O 移到后台后,还要确认 UI 没有同步等它。

减少Activity的跳转层次

下面保留几种历史窗口切换示意。系统启动窗口是否显示、显示时机和退出过渡受启动类型与系统版本影响;不是点图标就必定立即出现,也不是 AppWindow 对象一创建便完成交接。Android 12+ 应结合 SplashScreen 生命周期理解。

默认 App 的启动窗口流程

1
2
StartingWindow(SystemWindow)
->MainActivity(AppWindow)

大部分三方 App 启动流程

1
2
3
StartingWindow(SystemWindow)
-> SplashActivity(AppWindow)
-> MainActivity(AppWindow)

糟糕一点的启动流程是这样的

1
2
3
4
StartingWindow(SystemWindow)
-> MainActivity(AppWindow)
-> SplashActivity(AppWindow)
-> MainActivity(AppWindow)

更糟糕一点的启动流程:去掉了 StartingWindow

1
2
SplashActivity(AppWindow)
-> MainActivity(AppWindow)

减少无意义的 Activity 中转通常有助于缩短路径,但应保留登录、深链和状态恢复所需的路由。图中的“糟糕”是对当时体验的概括,不是禁止一切 SplashActivity 的平台规则。

厂商优化

下面保留系统及厂商优化的分类。除有版本化源码的项目外,其余多为 2019 年的观察线索,具体覆盖范围和当前实现未确认。App 的优化与验收不能依赖某个未公开的厂商策略。

启动加速

系统可以通过调度、性能提示和频率策略帮助启动,但幅度受到温控、电量、竞争负载与厂商实现约束,没有“绝对资源倾斜”的跨设备保证。

图中可见多核频率、频率限制与调度轨道,没有提供所有数值和策略配置,不能只凭密集颜色证明启动 App 独占 CPU、I/O、GPU。厂商资源调度 SDK 也需要具体文档与适用设备,不能把请求提示当成保证拿到大核。

PreFork

Android 10(Q)引入 USAP(Unspecialized App Process)池:预先派生未专门化为某个 App 的进程,符合条件的启动再将其专门化。它不是把已运行过其他 App 的进程反复复用。

Android 10 ZygoteProcess 的默认配置为关闭,实际是否启用取决于设备配置;还要满足参数与启动条件。Android 16 仍检查策略与可用性,USAP 通信失败可回退普通 Zygote 路径。普通 App 不能据此要求所有 Android 10+ 设备必走进程池。

下面保留原采样的进程及内存输出,包括原来的标点。它只能证明这次快照有这些 usap 进程,不能推算固定池大小、每次 fork 耗时或所有设备的内存成本。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2,348K: usap32 (pid 18731)
2,346K: usap32 (pid 18702)
2,343K: usap32 (pid 18707)
2,342K: usap32 (pid 18729)
2,341K: usap32 (pid 18711)
2,335K: usap32 (pid 20322)
2,335K: usap32 (pid 20325)
2,333K: usap32 (pid 20319)
2,333K: usap32 (pid 20320)
2,333K: usap32 (pid 20321)


1,509K: usap64 (pid 21169)
1,509K: usap64 (pid 21180)
1,507K: usap64 (pid 21171)
1,452K: usap64 (pid 21513)
1,450K: usap64 (pid 21506)
1,449K: usap64 (pid 21512)
1,447K: usap64 (pid 21511)
1,445K: usap64 (pid 21514)

启动消息重排

这是原文记录的厂商方向,没有给出具体公开版本实现。改变启动消息顺序必须保持生命周期、同步屏障和依赖语义;普通 App 不应把任意消息插到队首当成通用加速方案。

主线程、渲染线程加速

厂商可在特定阶段调整调度组、CPU 亲和性或性能提示。主线程/RenderThread 是否跑在大核上要看 Trace 与设备策略,不是所有启动的固定规则;强制迁核也可能带来温控或竞争代价。

启动预测

系统或厂商可能根据历史使用行为预热进程、代码或数据。具体预测策略属于设备实现;预热进程不等于目标 Activity 已存在,下一次也不必然是热启动。测量时把命中预热与未命中的情况区分开。

后台保活

系统会依据进程重要性和资源压力管理后台进程,部分厂商另有白名单或用户设置。保留进程可以减少部分初始化,但不能保证下次热启动,也不能保证一直存活。

后台重启

原文提到的“后台无感重启”属于未注明版本的厂商观察,不能作为 Android 标准启动机制。重启可能暂时释放泄漏内存,却不能修复泄漏或持续崩溃的根因,也不保证用户状态无损或下次热启动。

内存优化

大内存场景可能在启动时触发回收、缺页或资源竞争。系统可回收缓存页,必要时处理低优先级进程,但不是每次内存不足都必须杀掉很多 App。厂商提前回收只是可能的策略;收益要连同其他 App 被回收后重启的代价一起看。

优化启动逻辑

系统更新也可能缩短启动路径。下面是原文保留的 2019 年 ViewRootImpl 修改截图:提交说明为 “Immediately start drawing when becoming visible”,删除新 Surface 场景下推迟绘制的旧逻辑,并提到当时可能带来 5–10 ms 延迟。

这是一个具体系统分支的修复线索,不能推广成“App 减少 doFrame 次数必然加速”,也不能把提交说明里的收益当作当前设备测试结果。

参考文章

  1. 都9102年了,Android 冷启动优化除了老三样还有哪些新招?
  2. App startup time
  3. 历时1年,上百万行代码!首次揭秘手淘全链路性能优化(上)
  4. 极客时间 : Android 高手开发课
  5. Facebook-Redex
  6. 关于 Android 异步启动框架 alpha 的思考
  7. 支付宝 App 构建优化解析:通过安装包重排布优化 Android 端启动性能
  8. Redex 官网
  9. Redex 初探与 Interdex:Andorid 冷启动优化
  10. Android性能优化笔记(一)——启动优化

本文其他地址

由于博客留言交流不方便,点赞或者交流,可以移步本文的知乎或者掘金页面

知乎 - Android App 启动优化全记录

关于我 && 博客

下面是个人的介绍和相关的链接,期望与同行的各位多多交流,三人行,则必有我师!

  1. 博主个人介绍 :里面有个人的微信和微信群链接。
  2. 本博客内容导航 :个人博客内容的一个导航。
  3. 个人整理和搜集的优秀博客文章 - Android 性能优化必知必会 :欢迎大家自荐和推荐 (微信私聊即可)
  4. Android性能优化知识星球:付费社群已于 2026 年停止运营,不再招收新成员;此处保留历史介绍。

一个人可以走的更快 , 一群人可以走的更远

微信扫一扫

CATALOG
  1. 1. 应用启动概述
    1. 1.1. 应用启动的一般流程
    2. 1.2. 冷启动和热启动
    3. 1.3. 启动速度的测量
  2. 2. App 优化
    1. 2.1. 启动窗口优化
    2. 2.2. 线程优化
    3. 2.3. 系统调度优化
    4. 2.4. GC 优化
    5. 2.5. IO 优化
    6. 2.6. 资源重排
    7. 2.7. 类重排
    8. 2.8. 主页面布局优化
    9. 2.9. 闲时调用
    10. 2.10. 类加载优化
    11. 2.11. App 瘦身
    12. 2.12. 选择合适的启动框架
    13. 2.13. 启动网络链路优化
      1. 2.13.1. 问题和优化点
      2. 2.13.2. 优化
    14. 2.14. 预加载
    15. 2.15. 保活
    16. 2.16. 业务梳理
    17. 2.17. 业务优化
    18. 2.18. 减少Activity的跳转层次
      1. 2.18.1. 默认 App 的启动窗口流程
      2. 2.18.2. 大部分三方 App 启动流程
      3. 2.18.3. 糟糕一点的启动流程是这样的
      4. 2.18.4. 更糟糕一点的启动流程:去掉了 StartingWindow
  3. 3. 厂商优化
    1. 3.1. 启动加速
    2. 3.2. PreFork
    3. 3.3. 启动消息重排
    4. 3.4. 主线程、渲染线程加速
    5. 3.5. 启动预测
    6. 3.6. 后台保活
    7. 3.7. 后台重启
    8. 3.8. 内存优化
    9. 3.9. 优化启动逻辑
  4. 4. 参考文章
  5. 5. 本文其他地址
  6. 6. 关于我 && 博客