可能是东半球最好的Android面试资料
视频版 内容更丰富体验更佳哦
B站链接 www.bilibili.com/video/BV1BA...
---------------------------------------------------阴阳割昏晓---------------------------------------------
背景
最近在使用拼多多购物,除了价格比较香之外,每次冷启打开的体验非常好,作为一个Android开发不免好奇 简单分析记录一下
冷启数据
体验好,让我想到了郭德纲的那句话"全靠同行的衬托",那找几个同行过来对比下,这里使用淘宝、京东、闲鱼,从点击开始图标开始录个屏直接数秒,
测试手机是 华为 Mate 60
我这个样本比较少,机器性能也比较好,仅仅是个人对比,不代表大众使用的真实情况
可以粗略的看几个常见app的冷启对比下,这里录屏使用的剪映来分析 帧率为 每秒30帧,后面会涉及一些时间换算
拼多多
无广告冷启动 从点击图标到到首页完整展示 大概花了 29帧, 1000ms * 29/30 约为 0.96s ,太惊人了,基本冷启秒开
拼多多可能真的没有开屏广告,我印象中没有见过拼多多的开屏广告
淘宝
无广告冷启东 从点击图标到到首页完整展示 大概花了 1s+21帧, 1000ms+ 21/30*1000ms = 1.7s 还可以
淘宝可能没有开屏广告,或者非常克制,我刷了十几次都没有见到开屏广告
京东
无广告冷启京东 从点击图标到到首页完整展示
大概花了 1s+28帧, 1000ms + 28/30*1000ms 约为 1.93s 也是不错的
不过京东的开屏有开屏广告,但是做了用户频控,刷了几次就没了,这里仅对比无广告冷启开屏
闲鱼
毕竟是国内最大的二手平台(虽然现在小商家也特别多),而且是flutter深度使用者,看看它的表现 大概花了** 2s+10帧** 2000ms+ 10/30*1000ms 约为 2.3s
从上面数据来看,怪不得 我使用拼多多之后,打开app 确实比较舒服,因为我就是奔着买东西去的,越快到购物页面越舒服的。或许这就是极致的用户体验吧
首屏细节
拼多多的首页数据咋这么快就准备好了,网络耗时应该也有呢,应该是它提前准备好了数据 我们来实操验证下
- 切后台的截图
我们记住 手枪、去虾线、行李箱、停电 这几个卡片
冷启打开之后首先展示的是 还是切后台之前的数据 紧接着网络数据到了做了一次屏幕刷新
到这里大概就明白了,冷启使用上次feeds流的数据,先让用户看到数据,然后等新数据请求到之后再刷新页面就好
为了严谨点,把缓存数据清除的话,那么肯定首次冷启白屏,ok最后再验证一下
此时冷启白茫茫的一片,看来拼多多的策略还是让用户尽快进应用优先,或者这里并没有刻意设计🤔,都是先进首页有缓存就使用 没有的话就等网络数据,毕竟这种情况也只是新用户或者缓存数据过期才会这样
因此这里我可以得出把这种缓存优先的技术方案也可以学习学习,看看我们自己的app是不是可以复用一下,绩效这不就来了吗🤔 首页 = 数据 + UI 数据是使用缓存,UI也能吧一些UI组件提前预加载,不过这里也无法判断 是否预加载了首页UI🤔
开屏无广告
我目前在字节就是搞广告的,所以对广告稍微敏感些,开屏广告是一个很棒收入来源,特别是合约广告这种,之前应用冷启时间长,有时候其实是故意抽出一些时间来等待冷启的开屏广告, 但是我试了很多次,确实没看过拼多多的开屏广告,不过从这个结果来看 肯定是 经过严密的ab实验,不过拼多多在开屏广告上确实比较克制,
关于现在互联网的计算广告业务还是蛮有意思的比如 广告类型有 开屏、原生、激励、插屏、横幅,sdk类型有单个adn或者聚合广告sdk,有时间再单独分享几篇。
冷启优化一些常见手段
冷启动往往是大型应用的必争之地
- 实打实的提升用户体验
- 可能会带来一些GMV的转化
拼多多技术是应该是有些东西的,但是非常低调,属于人狠话不多那种,也没找到他们的方案。这里结合自身经验聊聊这块,主要是以下4个阶段结合技术手段做优化
Application attachBaseContext
这个阶段由于 Applicaiton Context 赋值等问题,一般不会有太多的业务代码,可能的耗时会在低版本机器4.x机器比较多,首次由于MultiDex.install耗时
dex 的指令格式设计并不完善,单个 dex 文件中引用的 Java 方法总数不能超过 65536 个,在方法数超过 65536 的情况下,将拆分成多个 dex。一般情况下 Dalvik 虚拟机只能执行经过优化后的 odex 文件,在 4.x 设备上为了提升应用安装速度,其在安装阶段仅会对应用的首个 dex 进行优化。对于非首个 dex 其会在首次运行调用 MultiDex.install 时进行优化,而这个优化是非常耗时的,这就造成了 4.x 设备上首次启动慢的问题。
可以使用一些开源方案,比如 github.com/bytedance/B... 不过 这里优化难度比较大,roi的话 看看app低版本的机型占比再做决定
ContentProvider
这里要注意检查 ContentProvider,特别是一些sdk在 AndroidManifest 里面注册了自己的 xxSDkProvider,然后在 xxSDkProvider 的 onCreate 方面里面进行初始化,确实调用者不需要自己初始化了,可却增加了启动耗时, 我们可以打开 Apk,看一下最终merge的 AndroidManiest 里面有多少 provider,看一下是否有这样的骚操作,往往这里容易忽视,这种情况可以使用谷歌App Startup来收敛ContentProvider
Application 优化
- 精简Application 中的启动任务
- 基于进程进行任务排布,比如常见的push进程、webview进程
西瓜视频 在冷启优化就将 push、小程序、sandboxed这几个进程做了优化拿到一些不错的收益mp.weixin.qq.com/s/v23jEhF9k...
搞进程难度大风险高
- 启动链路任务编排
这里需要先梳理启动链路,做成1任务编排,
- 比如之前串2.2行的,搞成并行初始化
- 核心任务做有向无环图(DGA)编排,非核心的延迟初始化
idlehandler是个好东西。
关于初始化DGA框架有不少框架,谷歌官方也有个 App Startup,感兴趣可以研究下
首页优化
首页是用户感知到的第一个页面,也是冷启优化的关键,前面也提过 首页 = 数据 + UI
- 数据 可以使用缓存
- UI的话 通常是xml解析优化,或者预加载
在性能较差的手机上,xml inflate 的时间可能在 200 到 500 毫秒之间。自定义控件和较深的 UI 层级会加重这个解析耗时。 一些框架比如x2c,或者AsyncLayoutInflater 可以帮助我们在UI这里做做文章
- 插件化
把非核心模块做成插件,使用时候下载使用,一劳永逸,不过插件化也有各种弊端
后台任务优化
主线程相关耗时的优化,事实上除了主线程直接的耗时,后台任务的耗时也是会影响到我们的启动速度的,因为它们会抢占我们前台任务的 cpu、io 等资源,导致前台任务的执行时间变长,因此我们在优化前台耗时的同时也需要优化我们的后台任务
- 减少后台线程不必要的任务的执行,特别是一些重 CPU、IO 的任务;
- 对启动阶段线程数进行收敛,防止过多的并发任务抢占主线程资源,同时也可以避免频繁的线程间调度降低并发效率
- GC 抑制
触发 GC 后可能会抢占我们的 cpu 资源甚至导致我们的线程被挂起,如果启动过程中存在大量的 GC,那么我们的启动速度将会受到比较大的影响。通过hook手段在启动阶段去抑制部分类型的 GC,以达到减少 GC 的目的。这个就比较高端了,也是只在一些大厂文章里面见过。
OK 本期就到这里了