一、启动优化概述
1、背景介绍:
- 应用的第一体验,唯一要求
快
: 即能快速进入主页面 ; - 八秒定律(用户在8秒时间未打开应用,70%的用户会放弃等待);
2、启动分类:
- 冷启动: 耗时最多,作为应用启动的衡量标准 ;
- 热启动: 最快 后台->前台 ;
- 温启动: 较快 重走Activity的生命周期 ;
3、冷启动流程:
- 点击桌面应用图标, 启动App;
- 加载空白Window;
- 创建进程;
- 创建Application;
- 启动主线程;
- 创建MainActivity;
- 加载布局;
- 绘制屏幕;
- 首帧绘制;
4、优化方向:
- 白屏处理;
- Application中任务的处理;
- Activity生命周期处理;
二、启动时间的测量方式
1、adb命令: adb shell am start -W packagename/首屏Activity
- ThisTime: 最后一个Activity启动耗时;
- TotalTime: 所有Activity启动耗时;
- WaitTime: AMS启动Activity的总耗时;
- 特点:
- 线下使用方便, 不能带到线上;
- 非严谨, 精确的时间;
2、手动埋点: 启动时埋点, 启动结束埋点, 二者差值
- 误区: onWindowFocusChanged只是Activity首帧时间, 并不代表界面已经展示出来;
- 正解: 真实数据展示出来,Feed第一条展示,首帧时间与真实数据展示出来还有一段距离;
- 起点: Application->attachBaseContext();
- 终点: 真实的第一条数据展示出来时打点;
- 特点: 精确, 可带到线上,
3、启动耗时的优雅的获取方式
- 手动埋点(常规实现): 代码入侵性强, 工作量大;
- AOP实现: 针对同一类问题统一处理, 无侵入, 修改方便;
4、启动耗时的分析工具
- traceView
- systrace
- profiler
三、优化实现
1、白屏处理:
- Theme切换: 感觉上快, 利用空白的window(现有90%以上应用使用);
SplashScreen
(Andorid 12 官方提供的启动实现方案, 可向后做兼容), 运行效果如下:
2、异步优化(Application及Activity中任务处理):
- 启动任务Task化, 启动逻辑抽象为Task;
- 根据所有任务依赖关系排序生成一个有向无环图(算法核心);
- 多线程按照排序后的优先级依次执行;
- 解决必须在主线程执行及有依赖关系的task;
3、延迟初始化方案
- 常规初始化痛点:
- 时机不便控制;
- 导致Feed卡顿;
- 更优方案:
- 核心思想: 对延迟任务进行分批初始化
- 利用IdleHandler特性, 空闲执行;
四、优化总方针: 异步, 延迟, 懒加载; 技术, 业务相结合
- 使用systrace检测 cpu time未跑满, 可充分利用;
- 完善监测: 监测Application及Activity中任务的耗时情况;
- 启动任务代码修改权限控制, 需要严格review;
五、微微工作优化方案
1、现状(启动耗时3.5s~4s)
- 白屏未处理
- 开屏页动画为播放的视频, 时间过长(产品设计不合理, 实现方式不合理)
- 启动任务未做处理
2、优化方案
- 使用
SplashScreen
处理白屏及动画问题, 需要产品与开发共同讨论下合适的实现方案; (该方案落地可将启动耗时降为1.5s以下, 收益较大) - 启动任务Task(设计耗时, 实现难度较大), 可作为持续优化任务实行, 该方案落地后可将耗时降为1s左右, 现有业务重的情况下可延后实行;