一文秒懂:优酷 Android 发现页的冷启动优化

一、背景

提到性能优化,跟页面相关的就两个指标:冷启动时长和页面 FPS 冷启动时长用来表征用户在首次打开页面时到页面渲染完成的耗时,很明显这个耗时越短,用户的体验将会越好。而 FPS 则表示页面渲染的帧率,FPS 越高,表示页面交互越流畅。所以我们的目标是:冷启动时长得低,FPS 得高,这样就表示用户能快速进入页面并且愉快的交互了。

随着业务复杂度的增加,发现页线上的冷启动耗时有点差强人意,于是就有了这一波发现页的冷启动优化。

二、思路

基于以前优化经验,迅速整理出了优化思路,并形成如下脑图:

在这里插入图片描述

三、优化结果

1)低端机自然冷启到页面渲染完毕进 1s,目前实验室数据 892ms,行业对比数据如下:
在这里插入图片描述
2)低端机 push 冷启到视频起播进 5s,优化前后对比效果如下:
在这里插入图片描述

四、主路径梳理

针对发现页,对其启动主路径梳理如下:
在这里插入图片描述
在这里插入图片描述

五、懒加载

依赖阿里中间件 AppMonitor 的页面完成的回调接口,通过将所有可以懒加载的任务用 MonitorTask 包装后抛给 PageMonitorTaskDomain 在合适的时机执行,如:当 page 处在可交互的状态时执行:

@Override
public void onPageChanged(final String name, final int state, final long l) {
    
    
   if (state = INTERACTIVE) {
    
    
      doDelayedTask();
   }
}

几个主要的懒加载项:

1)Tab 动画;

2)Poplayer;

3)卡片推荐任务;

4)Viewpager 左右 Tab 懒加载;

5)各种业务(换肤、福利球等)。

六、预加载

创建预加载池,会在 Application OnCreate 中启动异步线程,加载需要被预加载的资源。

1)预创建 Tabview,预加载 Tab 数据,预解析 Tab 数据;

2)预加载类;

3)预加载关注 SDK;

4)预加载主 Fragment;

5)预加载 Delegate;

6)预加载以及预处理缓存以及快照。

七、其他优化

1)直接创建 Delegate,而非通过配置文件配置再反射创建;

2)整合 Delegate,减少向 EventBus 的注册次数;

3)减少字符串拼接操作。

八、快照

由于缓存数据处理是异步的,低端机进入发现后,等待缓存数据处理完成总得有个 Loading 界面,即使提前预加载缓存数据以及预处理好,低端机也不能避免 Loading,为了让用户不再看到过渡页面或者菊花,就得保证主线程能够带着数据渲染,而不是等数据好了后再更新界面。可惜的是,即使缓存反序列后,通过一顿猛如虎的操作:创建 Model、创建 Adapter、卡片布局优化,还是需要 200ms 的时间渲染 3 张卡片。最后,只能通过加载轻量级的缓存数据——快照来完成首屏的展示,加载缓存数据拢共分三步:

1)缓存数据的时候保存一份快照,只保留最简单的一些属性(低质量封图链接,PGC 信息);

2)预加载快照,预创建用于展示快照的容器 view(inflate 或者直接代码实现都可以);

3)进入发现后,优先展示快照,得缓存数据渲染完后,移出快照。

优化后的效果如下:
在这里插入图片描述

九、Push 冷启

借助自然冷启的优化成果以及 push 链路的特殊性——以视频起播为目标,特地针对 push

冷启做了以下优化:

1)预加载视频资源;

2)预初始化播放器;

3)去掉 Push 链路不需要的异步任务(缓存以及快照相关的逻辑);

4)调整 Push 链路,以视频起播为最高优先级,改造后的链路如下:

在这里插入图片描述

十、总结

启动优化主旨就一个:主线程只做 UI 操作。相伴的手段就是异步预加载,同步懒加载。另外也需要具体场景具体分析,大体步骤就是:通过工具导出启动 Trace 日志,分析整个启动路径的耗时因素,优先解决明显的耗时问题,后续再各个击破。一般情况下,在优化到可接受的目标后即可,而不需要优化到极致,因为性能的优化往往会带来额外的复杂度,比如以上提到的 Push 场景和正常的启动场景就不能复用相同的逻辑。

优化达到目标后需要守护住成果,在日常开发时需要严格守住 UI 线程的底线,上线后需要时常关注性能数据,这样攻防坚守才能持续交付高性能的成果。

作者 :阿里文娱高级开发工程师 纸贵

猜你喜欢

转载自blog.csdn.net/alienttech/article/details/106735280