启动优化
启动时间定义
用户点击icon到用户看见feed流的时间
从业务角度看全流程
- 开屏广告涉及到网络请求
- 开屏广告
方案
- 开屏广告请求尽量提前
- 请求时尽量完成对启动流程有block的任务
- feed流做缓存
从技术角度看全流程
整体流程分为application阶段、Activity阶段、Fragment阶段
Application阶段
- Intstall Provider初始化
- Appcliation.onCreate: 非常臃肿.异步、按需、预加载
Activity
Activity
阶段的起点来自于 ActivityThread#performLaunchActivity
的调用,在 performLaunchActivity
方法中,将会创建Activity
的上下文,并且反射创建Activity
实例,如果是App的冷启动(即 Application
并未创建),则会先创建Application
并调用Application
的onCreate
方法,再初始化Activity
,创建Window
对象(PhoneWindow
)并实现Activity
和Window
相关联,最终调用到Activity
的onCreate
生命周期方法。
在启动优化的专项中,Activity
阶段最关键的生命周期是 Activity#onCreate
,这个阶段中包含了大量的 UI 构建、首页相关业务初始化等耗时任务,是我们在优化启动过程中非常重要的一环,我们可以通过异步、预加载、延迟执行等手段做各方面的优化。
线上大盘
- 监控1s、2s、3s、5s比例
- 90分位
开发阶段
//todo Basti611
MethodTrace
思路
- 低成本低风险快速降低
- 高成本突破
Application流程
启动任务删减和重排
- 必须要存在的任务:网络库、存储库、图片库
- 业务相关:长链接(后台)
- 启动结束后再执行
任务启动框架
支持依赖关系、
IdleHandler
Activity流程
广告Activity和MainActivity合并
原本流程:进入广告Activity,加载本地广告数据缓存展示广告+拉取广告数据;如果没有广告数据或者广告数据过期再进入主页.
问题:在加载广告和展示广告期间没办法做一些预加载.同时要连续启动两个Activity,这也会带来耗时.
解决方案:把广告业务封装成一个组件,抽离成一个View,将广告View添加进DecorView,同时后面的首页框架就可以加载了
Tab懒加载
布局懒加载
ViewStub + lazy
大对象反序列化
- 用Gson解的,自定义 TypeAdapter,属于正面优化反序列化操作本身(市面上有现成的一些通过添加注解自动生成TypeAdapter的框架,通过一个注解就能够很轻松的给对应的类生成 TypeAdapter并注册到 Gson 中)
- 又大又乱又不好改的直接读磁盘然后 JSON 解析的大对象(没想到还有这种的吧),提前子线程预加载,避免在 UI 线程反序列化,能解决部分问题,并非完全的解法