客户端加载耗时优化方案(上)
编辑导语:我们经常能碰到客户端加载耗时的情况,那么应该如何优化解决这种问题,提升用户体验感呢?本文作者总结了刷新加载loading的三个阶段,在本篇文章中,主要是针对第一阶段,为我们阐述了优化方案。
任何一件事情的发生可能背后有很多种原因,要解决好一个问题,都要明确造成这个问题的原因是什么,然后针对这些原因进行优化。
在刷新加载loading的过程,经历了三个阶段:
- 客户端触发顶部刷新;
- 服务器收到请求后准备要下发的数据;
- 客户端收到服务器数据进行展示。
本文针对第一阶段:“客户端触发顶部刷新”聊一聊怎么减少耗时问题(下一篇文章会针对另外两个阶段阐述优化方案)。
01
交互层面:使用占位策略缓解用户焦虑
app某个界面一直空白,或者界面一直在转loading,在这样的过程中,用户任何信息都获取不到,会让用户产生等待焦虑。
1)动画策略
动画策略是一个比较常用的策略,比如可以使用新颖的加载动画来代替老式的loading菊花样式,用户在看动画的过程中加载就已经结束了,以此降低用户预期的等待时长。
但新颖的动画不一定适用所有App,不恰当的使用新颖的加载动画甚至会加重某些用户的等待焦虑,造成用户流失。所以当你决定要采用动画策略时,不妨采用A/B Test的方式进行测试,看看新动画是否真的有降低等待焦虑的作用。
2)历史内容策略
历史内容占位是目前主流App最常用的策略,除了用户首次登陆App没有历史信息外,其余每次登陆都会先使用历史内容来进行占位,以此来减少页面空白加载给用户带来的焦虑。
02
技术层面:预拉取
预拉取的基本操作
预拉取,也即提前拉取,在用户真正触发向后台拉取内容的网络请求之前,就已经准备好数据,等到用户真正开始拉取时,直接把上次提前拉取好的数据返回给用户,这种操作甚至可以让用户体会到瞬间拉取的效果。
图1- 常规拉取流程
图2-预拉取流程
如上图所示,预拉取的最关键的问题在于:何时触发预拉取?
用户自然希望每次拉取时,客户端都把数据拉取好,这样每次都可以体会到瞬间拉取的效果。那么最直接的方法就是:在一切用户未进行网络请求的时刻,一直向后台请求最新的数据。
但从用户流量,服务器所能接受的并发请求上限来看,上面这种策略不仅会浪费用户流量,甚至在用户数量多的情况下会把服务器搞挂掉,这就得不偿失了。
我们不妨换个思路,如果我们是用户,我们在什么情况下对拉取内容耗时要求最高?
那自然是我们对内容最迫切的时候,比如:
- 收到了新通知的红点
- 首次打开app
下面我们针对”红点预拉取”和”首次预拉取”讨论下具体的产品方案。
03
红点预拉取
在介绍红点预拉取之前,我们先明确下红点本身的定位,红点大致可以被分为两种类型:
- 消息型红点:比如朋友圈和视频号的红点,会在你的朋友有输出型行为(点赞、发表、评论等)时给予你通知,这种红点强调实时性,需要具有过期和撤回的能力;
- 功能型红点:不强调实时性,一般在给用户介绍新功能时起引导的作用,只有当你手动点击时这种红点才会消失,这种红点基本不需要具备过期和撤回的能力。
因为我们需要通过预拉取来获取新的内容,遂下面讨论的主要是”消息型红点”。
红点在app中无处不在,以朋友圈举例,当我在发现页收到一个”同事A的头像+小红点”类型的红点,这时在我点进朋友圈之前,我内心的预期自然是想看 同事A 点赞了什么内容。
在我点进朋友圈如果加载的loading时间过长,我的预期就没有被满足。
那么用红点预拉取怎么做呢?
当我收到”同事A的头像+小红点”类型的红点(红点中要带上”同事A刚发的那条内容背后的id”)时,客户端立马通过这个id去服务器请求内容数据,客户端收到内容数据中先存在缓存里。
当我真正点进朋友圈触发顶部刷新时,这时直接把我已经从服务器拉取到数据进行展示。这样的一个流程可以被称为”红点预拉取”。
但是, 红点预拉取就这么简单吗?非也非也。
我们不妨看几个关于红点预拉取的问题(相关解释在文末~):
- 问题1:用户收到红点之后对红点对应的内容进行了预拉取,但这条内容在客户端收到红点和发起内容之间被作者删除了,也就是预拉取拉不到内容了,怎么办?
- 问题2:用户收到A红点后,客户端对A内容进行了预拉取,但在真正消费预拉取内容之前,A内容因为安全问题被处罚打击删除了,这时A红点会被撤销,那已经预拉取的内容怎么办?
- 问题3:用户收到A红点后,客户端对A内容进行了预拉取,但在真正消费预拉取内容之前,用户又收到了B红点,且B红点把A红点进行了覆盖,那么已经预拉取过的A内容该怎么办?
- 问题4:用户收到A红点后,客户端对A内容进行了预拉取,但用户在12小时候之后才进入了朋友圈,这时应该展示A内容吗?
04
旁路预拉取
旁路预拉取在多tab的产品中较为常用,以抖音为例,抖音有”同城、关注、推荐”这三个主流tab,目前抖音出现频率最多的红点为关注红点。
大部分人点进抖音都是进入了”关注tab”,关注tab可以通过红点触发预拉取,但在用户点到推荐tab时,因为推荐tab没有做预拉取,所以用户顶部刷新加载内容耗时会比较长(大约2s),很多用户在这2s内就离开了抖音。
既然关注tab可以有红点触发的预拉取,关注tab的拉取耗时进行了优化,那我们能不能让关注tab帮一帮推荐tab(或同城tab)呢?
答案是可以的,这时就可以采取”旁路预拉取”。
客户端在关注tab加载数据,向服务器请求数据时,服务器可以和客户端约定一个开关:enablePrefectSwitch。
当服务器给客户端下发了 enablePrefectSwitch 等于 YES 的指令,我们就去预拉取推荐tab的内容,那么当用户在关注tab刷完内容切到推荐tab,会发现推荐tab的拉取耗时很短(因为已经做了预拉取了)。
问题1:服务器应该什么时候告诉客户端enablePrefectSwitch 等于 YES 呢?
问题2:在关注tab触发旁路预拉取去进行推荐tab的预拉取,在推荐tab预拉取成功前,用户就已经切到了推荐tab手动进行了顶部刷新,那么这个时候推荐tab要展示的是预拉取的内容,还是手动触发顶部刷新的内容?
05
1. 曝光预拉取
以微信为例,当用户切到发现页时,会曝光”朋友圈”的入口,也会曝光”视频号”的入口,曝光预拉取也即当入口曝光时,触发预拉取的逻辑。
曝光预拉取的策略比较好理解,但也有一些需要注意的小问题(相关解释在文末~):
问题1:如果客户端采取曝光预拉取的策略,从访问流量上考虑,服务器需要注意什么问题呢?
06
定时预拉取:
定时预拉取比较好理解,即每隔n分钟触发一次预拉取。
定时预拉取的策略比较好理解,但也有一些需要注意的小问题(相关解释在文末~):
问题1:以微信这样的产品为例,如果打算对视频号采取定时预拉取(比如每10分钟就对视频号内容进行预拉取),会不会有问题?
问题2:采取定时预拉取,用户首次启动app时(也即0分钟时),是否要进行预拉取?
07
预拉取要注意的细节
1)方案兼容问题
我们发现以上的预拉取方案都有一定的缺点,所以实际工程中一般是将上面所有方案兼容起来,取长补短。
比如以红点预拉取为主体,其它预拉取方案作为辅助的产品策略。
红点预拉取到的内容被用户使用的概率比较大,旁路预拉取可以优化多tab浏览时用户切tab的体验,曝光预拉取与定时预拉取相结合,解决某些App厂商在某些时间点统一杀App进程导致后台在某个时间点访问点突增的问题。
在红点撤销、热门红点过期、新增热门红点时候丢弃之前预加载的内容,但在有红点的背景下触发 旁路、曝光或定时 预拉取时,要带上相应的红点信息。
2)预拉取要做假耗时
这里需要注意一个交互上的细节,预拉取的初衷是降低拉取的等待耗时,但如果将等待耗时降低到了0秒,可能会给用户一种并没有拉取成功,而是展示了历史占位的错觉。
所以即使客户端已经进行了内容预拉取,在用户触发加载时也要等待0.5s后再给用户展示数据,当然这0.5s是个经验值,实际工程中可以通过实验进行配置,找到一个既让用户感受到加载的过程,又能尽可能多的降低用户等待焦虑的时间点。
3)在预拉取方案下,所有的网络请求都应该设计成串行的
看到这里,你可能会发现采用预拉取会有一个风险点:预拉取的请求(标记为预拉取A) 和 用户手动刷新的请求(标记为手动拉取B) 同时请求了服务器,那么用户到底应该展示哪个内容?
这里有两个方案:
- 用户触发手动拉取B时,主动取消掉上一次的预拉取A,用户展示的内容以手动拉取B为准;
- 用户触发手动拉取B时,这时发现预拉取A已经在请求服务器内容了,那么手动拉取B以预拉取A返回的数据为准。
附:实际上并发请求的后果比展示哪个内容更严重,并发请求甚至会导致数据丢失,或下发重复数据等问题。
08
预拉取存在的问题
通过上面的预拉取方案,实际过程中会发现两个问题:
- 高并发,后台服务器成本高;
- 红点频率推送高的产品,经常会在上一个红点预拉取内容还未消费前,就被新的红点给覆盖了,预拉取存在浪费的情况。
所以我们可不可以在减少预拉取频率的基础上,还能提高预拉取内容的使用率呢?答案是可行的,可以将人工智能和预拉取融合。
AI与预拉取:在展开讲解AI与预拉取策略之前,我们先做几个用户使用习惯的合理假设:
- 假设一:不同用户对不同的红点样式刺激不同,部分用户有着强烈查看特定红点内容的冲动;
- 假设二:不同用户使用产品的频率不同;
- 假设三:不同用户有着不同的高频使用产品的时间段,每个用户有着自己高频使用产品的特定时间段。
1)根据用户画像触发预拉取
根据假设一,A用户可能对某个明星发的内容红点比较好奇,B用户可能对自己爱慕的人发新内容的红点比较冲动,千人前面,每个人对不同红点代表的含义查看冲动不同。
可以通过建立模型来刻画用户感兴趣内容的用户画像,只针对用户感兴趣的消息红点触发预拉取,且可以提升这类红点的优先级,在不影响红点本身体系的情况下,让这类红点尽可能长的存在于用户界面上。
2)使用频率
根据假设二,有部分用户可能一直都接受到各种类型的消息红点,但始终没有对这类红点进行过消费。
所以针对这类用户可以适当的进行红点惩罚,比如20分钟内不再推红点,又或者降低红点触发预拉取的频率,只针对用户感兴趣的红点触发预拉取,当用户频率和画像越来越全面时,再动态调整预拉取策略。
3)使用时间段
根据假设三,不同用户的使用时段可能不同,比如A用户上班时间较长,可能只会在晚上11点-12点期间进行内容消费,白天大部分时间即使收到了红点也没有时间去查看,通过建立统计模型明确用户高频使用时长,在这段时间段内提升用户预拉取的触发频率。
09
相关问题解释:
1. 红点预拉取
问题1:用户收到红点之后对红点对应的内容进行了预拉取,但这条内容在客户端收到红点和发起内容之间被作者删除了,也就是预拉取拉不到内容了,怎么办?
答:这种情况下预拉取没拉取到内容是正常表现,应该启用红点撤回机制。
问题2:用户收到A红点后,客户端对A内容进行了预拉取,但在真正消费预拉取内容之前,A内容因为安全问题被处罚打击删除了,这时A红点会被撤销,那已经预拉取的内容怎么办?
答:A红点被撤销后,对应的预拉取的A内容就要进行销毁。也即:有A红点不一定要求有A内容,但A红点被撤销时,预拉取到的A内容一定也要撤销掉。
问题3:用户收到A红点后,客户端对A内容进行了预拉取,但在真正消费预拉取内容之前,用户又收到了B红点,且B红点把A红点进行了覆盖,那么已经预拉取过的A内容该怎么办?
答:B红点覆盖掉A红点后,应该先立即撤销掉对A内容的预拉取,接着再进行B内容的预拉取。
问题4:用户收到A红点后,客户端对A内容进行了预拉取,但用户在12小时候之后才进入了朋友圈,这时应该展示A内容吗?
答:A红点属于”消息型红点”,有时效性,12个小时都没有对A红点进行消费,那么A红点应该走过期销毁的逻辑,同时也应该撤销预拉取到的A内容。
2. 曝光预拉取
问题1:如果客户端采取曝光预拉取的策略,从访问流量上考虑,服务器需要注意什么问题呢?
答:早上8、9点是用户起床的高峰期,但这段时间可能公司还没有开始上班,针对这段时间用户访问的峰值要提前进行监控,防止出现服务器宕机事故。
3. 定时预拉取
问题1:以微信这样的产品为例,如果打算对视频号采取定时预拉取(比如每10分钟就对视频号内容进行预拉取),会不会有问题?
答:会有问题,微信主打即时通讯的产品,通讯才是最高频的使用场景。如果在微信打开期间都定时做视频号的内容预拉取,预拉取的内容被消费的几率不大,且可能会对服务器产生不必要的请求。
问题2:采取定时预拉取,用户首次启动app时(也即0分钟时),是否要进行预拉取?
答:有些安卓机出于性能考虑,会在某个时间点强杀所有app,所以在这种情况下所有用户重新打开app,对服务器的预拉取访问会出现一个突刺,而且用户打开app,实际上并不一定是要访问预拉取的内容,所以不建议在首次启动app时就直接去进行预拉取。
作者,和产品经理聊技术;公众号:和产品经理聊技术
本文由 @和产品经理聊技术 原创发布于人人都是产品经理,未经作者许可,禁止转载。
题图来自Unsplash,基于CC0协议。
讲得太好了!讲实践也讲原理, 基础逻辑很清晰,让小白也能看懂!感谢作者
插眼