注册

拼多多冷启真的秒开



背景


最近在使用拼多多购物,除了价格比较香之外,每次冷启打开的体验非常好,作为一个Android开发不免好奇 简单分析记录一下


冷启数据


体验好,让我想到了郭德纲的那句话"全靠同行的衬托",那找几个同行过来对比下,这里使用淘宝、京东、闲鱼,从点击开始图标开始录个屏直接数秒,



测试手机是 华为 Mate 60



我这个样本比较少,机器性能也比较好,仅仅是个人对比,不代表大众使用的真实情况


可以粗略的看几个常见app的冷启对比下,这里录屏使用的剪映来分析
帧率为 每秒30帧,后面会涉及一些时间换算
image.png


拼多多


无广告冷启动 从点击图标到到首页完整展示 大概花了 29帧,
1000ms * 29/30 约为 0.96s
,太惊人了,基本冷启秒开



拼多多可能真的没有开屏广告,我印象中没有见过拼多多的开屏广告



image.pngimage.png


淘宝


无广告冷启东 从点击图标到到首页完整展示
image.png
image.png
大概花了 1s+21帧,
1000ms+ 21/30*1000ms = 1.7s
还可以



淘宝可能没有开屏广告,或者非常克制,我刷了十几次都没有见到开屏广告



京东


无广告冷启京东
从点击图标到到首页完整展示
image.png
image.png


大概花了 1s+28帧,
1000ms + 28/30*1000ms 约为 1.93s
也是不错的



不过京东的开屏有开屏广告,但是做了用户频控,刷了几次就没了,这里仅对比无广告冷启开屏



闲鱼


毕竟是国内最大的二手平台(虽然现在小商家也特别多),而且是flutter深度使用者,看看它的表现
image.png
image.png
大概花了** 2s+10帧**
2000ms+ 10/30*1000ms 约为 2.3s


image.png
从上面数据来看,怪不得 我使用拼多多之后,打开app 确实比较舒服,因为我就是奔着买东西去的,越快到购物页面越舒服的。或许这就是极致的用户体验吧


首屏细节


拼多多的首页数据咋这么快就准备好了,网络耗时应该也有呢,应该是它提前准备好了数据
image.png
我们来实操验证下



  • 切后台的截图

我们记住 手枪、去虾线、行李箱、停电 这几个卡片
image.png


冷启打开之后首先展示的是 还是切后台之前的数据
image.png
紧接着网络数据到了做了一次屏幕刷新
image.png


到这里大概就明白了,冷启使用上次feeds流的数据,先让用户看到数据,然后等新数据请求到之后再刷新页面就好


为了严谨点,把缓存数据清除的话,那么肯定首次冷启白屏,ok最后再验证一下
image.png


此时冷启白茫茫的一片,看来拼多多的策略还是让用户尽快进应用优先,或者这里并没有刻意设计🤔,都是先进首页有缓存就使用 没有的话就等网络数据,毕竟这种情况也只是新用户或者缓存数据过期才会这样
image.png


因此这里我可以得出把这种缓存优先的技术方案也可以学习学习,看看我们自己的app是不是可以复用一下,绩效这不就来了吗🤔
首页 = 数据 + UI
数据是使用缓存,UI也能吧一些UI组件提前预加载,不过这里也无法判断 是否预加载了首页UI🤔


开屏无广告


我目前在字节就是搞广告的,所以对广告稍微敏感些,开屏广告是一个很棒收入来源,特别是合约广告这种,之前应用冷启时间长,有时候其实是故意抽出一些时间来等待冷启的开屏广告,
但是我试了很多次,确实没看过拼多多的开屏广告,不过从这个结果来看 肯定是 经过严密的ab实验,不过拼多多在开屏广告上确实比较克制,



关于现在互联网的计算广告业务还是蛮有意思的比如 广告类型有 开屏、原生、激励、插屏、横幅,sdk类型有单个adn或者聚合广告sdk,有时间再单独分享几篇。



image.png


冷启优化一些常见手段


冷启动往往是大型应用的必争之地



  1. 实打实的提升用户体验
  2. 可能会带来一些GMV的转化

拼多多技术是应该是有些东西的,但是非常低调,属于人狠话不多那种,也没找到他们的方案。这里结合自身经验聊聊这块,主要是以下4个阶段结合技术手段做优化
image.png


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 优化



  1. 精简Application 中的启动任务
  2. 基于进程进行任务排布,比如常见的push进程、webview进程

西瓜视频 在冷启优化就将 push、小程序、sandboxed这几个进程做了优化拿到一些不错的收益mp.weixin.qq.com/s/v23jEhF9k…



搞进程难度大风险高




  1. 启动链路任务编排

这里需要先梳理启动链路,做成1任务编排,



  1. 比如之前串2.2行的,搞成并行初始化
  2. 核心任务做有向无环图(DGA)编排,非核心的延迟初始化

idlehandler是个好东西。
image.png
image.png



关于初始化DGA框架有不少框架,谷歌官方也有个 App Startup,感兴趣可以研究下



首页优化


首页是用户感知到的第一个页面,也是冷启优化的关键,前面也提过 首页 = 数据 + UI



  1. 数据 可以使用缓存
  2. UI的话 通常是xml解析优化,或者预加载

在性能较差的手机上,xml inflate 的时间可能在 200 到 500 毫秒之间。自定义控件和较深的 UI 层级会加重这个解析耗时。
一些框架比如x2c,或者AsyncLayoutInflater 可以帮助我们在UI这里做做文章



  1. 插件化

把非核心模块做成插件,使用时候下载使用,一劳永逸,不过插件化也有各种弊端


后台任务优化


主线程相关耗时的优化,事实上除了主线程直接的耗时,后台任务的耗时也是会影响到我们的启动速度的,因为它们会抢占我们前台任务的 cpu、io 等资源,导致前台任务的执行时间变长,因此我们在优化前台耗时的同时也需要优化我们的后台任务



  1. 减少后台线程不必要的任务的执行,特别是一些重 CPU、IO 的任务;
  2. 对启动阶段线程数进行收敛,防止过多的并发任务抢占主线程资源,同时也可以避免频繁的线程间调度降低并发效率
  3. GC 抑制

触发 GC 后可能会抢占我们的 cpu 资源甚至导致我们的线程被挂起,如果启动过程中存在大量的 GC,那么我们的启动速度将会受到比较大的影响。通过hook手段在启动阶段去抑制部分类型的 GC,以达到减少 GC 的目的。这个就比较高端了,也是只在一些大厂文章里面见过。


OK 本期就到这里了


作者:程序员龙湫
来源:juejin.cn/post/7331607384932876326

0 个评论

要回复文章请先登录注册