首页 > 客户端加载耗时优化方案(上)
头像
鹅厂老王
编辑于 2020-11-20 13:37
+ 关注

客户端加载耗时优化方案(上)


任何一件事情的发生可能背后有很多种原因,要解决好一个问题,都要明确造成这个问题的原因是什么,然后针对这些原因进行优化。


在刷新加载loading的过程,经历了三个阶段:

1.客户端触发顶部刷新

2.服务器收到请求后准备要下发的数据

3.客户端收到服务器数据进行展示。


本文针对第一阶段:"客户端触发顶部刷新"聊一聊怎么减少耗时问题。(下一篇文章会针对另外两个阶段阐述优化方案)


01

交互层面:使用占位策略缓解用户焦虑

app某个界面一直空白,或者界面一直在转loading,在这样的过程中,用户任何信息都获取不到,会让用户产生等待焦虑。

动画策略

动画策略是一个比较常用的策略,比如可以使用新颖的加载动画来代替老式的loading菊花样式,用户在看动画的过程中加载就已经结束了,以此降低用户预期的等待时长。但新颖的动画不一定适用所有App,不恰当的使用新颖的加载动画甚至会加重某些用户的等待焦虑,造成用户流失。

所以当你决定要采用动画策略时,不妨采用A/B Test的方式进行测试,看看新动画是否真的有降低等待焦虑的作用。

历史内容策略

历史内容占位是目前主流App最常用的策略,除了用户首次登陆App没有历史信息外,其余每次登陆都会先使用历史内容来进行占位,以此来减少页面空白加载给用户带来的焦虑。


02

技术层面:预拉取

预拉取的基本操作

预拉取,也即提前拉取,在用户真正触发向后台拉取内容的网络请求之前,就已经准备好数据,等到用户真正开始拉取时,直接把上次提前拉取好的数据返回给用户,这种操作甚至可以让用户体会到瞬间拉取的效果。

2020-11-14-prefetch_Time-consuming_Ptimization_02_common_request.png

图1- 常规拉取流程

2020-11-14-prefetch_Time-consuming_Ptimization_01_prefetch_request.png

图2-预拉取流程

如上图所示,预拉取的最关键的问题在于:何时触发预拉取?

用户自然希望每次拉取时,客户端都把数据拉取好,这样每次都可以体会到瞬间拉取的效果。那么最直接的方法就是:在一切用户未进行网络请求的时刻,一直向后台请求最新的数据。

但从用户流量,服务器所能接受的并发请求上限来看,上面这种策略不仅会浪费用户流量,甚至在用户数量多的情况下会把服务器搞挂掉,这就得不偿失了。

我们不妨换个思路,如果我们是用户,我们在什么情况下对拉取内容耗时要求最高?

那自然是我们对内容最迫切的时候,比如:

  • 收到了新通知的红点

  • 首次打开app

下面我们针对"红点预拉取"和"首次预拉取"讨论下具体的产品方案。


03

红点预拉取

在介绍红点预拉取之前,我们先明确下红点本身的定位,红点大致可以被分为两种类型:

  • 消息型红点:比如朋友圈和视频号的红点,会在你的朋友有输出型行为(点赞、发表、评论等)时给予你通知,这种红点强调实时性,需要具有过期和撤回的能力;

  • 功能型红点:不强调实时性,一般在给用户介绍新功能时起引导的作用,只有当你手动点击时这种红点才会消失,这种红点基本不需要具备过期和撤回的能力。

因为我们需要通过预拉取来获取新的内容,遂下面讨论的主要是"消息型红点"。

红点在app中无处不在,以朋友圈举例,当我在发现页收到一个"同事A的头像+小红点"类型的红点,这时在我点进朋友圈之前,我内心的预期自然是想看 同事A 点赞了什么内容。在我点进朋友圈如果加载的loading时间过长,我的预期就没有被满足。

2020-11-14-prefetch_Time-consuming_Ptimization_12_wechat_Sns.png

那么用红点预拉取怎么做呢?

当我收到"同事A的头像+小红点"类型的红点(红点中要带上"同事A刚发的那条内容背后的id")时,客户端立马通过这个id去服务器请求内容数据,客户端收到内容数据中先存在缓存里。当我真正点进朋友圈触发顶部刷新时,这时直接把我已经从服务器拉取到数据进行展示。这样的一个流程可以被称为"红点预拉取"。

2020-11-14-prefetch_Time-consuming_Ptimization_03_redDot_request.png


但!是! 红点预拉取就这么简单吗?非也非也。

我们不妨看几个关于红点预拉取的问题(相关解释在文末~):

问题1:用户收到红点之后对红点对应的内容进行了预拉取,但这条内容在客户端收到红点和发起内容之间被作者删除了,也就是预拉取拉不到内容了,怎么办?

问题2:用户收到A红点后,客户端对A内容进行了预拉取,但在真正消费预拉取内容之前,A内容因为安全问题被处罚打击删除了,这时A红点会被撤销,那已经预拉取的内容怎么办?

问题3:用户收到A红点后,客户端对A内容进行了预拉取,但在真正消费预拉取内容之前,用户又收到了B红点,且B红点把A红点进行了覆盖,那么已经预拉取过的A内容该怎么办?

问题4:用户收到A红点后,客户端对A内容进行了预拉取,但用户在12小时候之后才进入了朋友圈,这时应该展示A内容吗?


04

旁路预拉取

旁路预拉取在多tab的产品中较为常用,以抖音为例,抖音有"同城、关注、推荐"这三个主流tab,目前抖音出现频率最多的红点为关注红点。

image.png

大部分人点进抖音都是进入了"关注tab",关注tab可以通过红点触发预拉取,但在用户点到推荐tab时,因为推荐tab没有做预拉取,所以用户顶部刷新加载内容耗时会比较长(大约2s),很多用户在这2s内就离开了抖音。

既然关注tab可以有红点触发的预拉取,关注tab的拉取耗时进行了优化,那我们能不能让关注tab帮一帮推荐tab(或同城tab)呢?

答案是可以的,这时就可以采取"旁路预拉取"。

客户端在关注tab加载数据,向服务器请求数据时,服务器可以和客户端约定一个开关:enablePrefectSwitch,当服务器给客户端下发了 enablePrefectSwitch 等于 YES 的指令,我们就去预拉取推荐tab的内容,那么当用户在关注tab刷完内容切到推荐tab,会发现推荐tab的拉取耗时很短(因为已经做了预拉取了)。

2020-11-14-prefetch_Time-consuming_Ptimization_04_bypass_request.png


问题1:服务器应该什么时候告诉客户端enablePrefectSwitch 等于 YES 呢?

问题2:在关注tab触发旁路预拉取去进行推荐tab的预拉取,在推荐tab预拉取成功前,用户就已经切到了推荐tab手动进行了顶部刷新,那么这个时候推荐tab要展示的是预拉取的内容,还是手动触发顶部刷新的内容?


05

曝光预拉取

以微信为例,当用户切到发现页时,会曝光"朋友圈"的入口,也会曝光"视频号"的入口,曝光预拉取也即当入口曝光时,触发预拉取的逻辑。

2020-11-14-prefetch_Time-consuming_Ptimization_05_entry_expose_request.png


曝光预拉取的策略比较好理解,但也有一些需要注意的小问题(相关解释在文末~):

问题1:如果客户端采取曝光预拉取的策略,从访问流量上考虑,服务器需要注意什么问题呢?


06

定时预拉取

定时预拉取比较好理解,即每隔n分钟触发一次预拉取。

2020-11-14-prefetch_Time-consuming_Ptimization_06_timing_request.png


定时预拉取的策略比较好理解,但也有一些需要注意的小问题(相关解释在文末~):

问题1:以微信这样的产品为例,如果打算对视频号采取定时预拉取(比如每10分钟就对视频号内容进行预拉取),会不会有问题?

问题2:采取定时预拉取,用户首次启动app时(也即0分钟时),是否要进行预拉取?


07

预拉取要注意的细节

a.方案兼容问题

我们发现以上的预拉取方案都有一定的缺点,所以实际工程中一般是将上面所有方案兼容起来,取长补短。

比如以红点预拉取为主体,其它预拉取方案作为辅助的产品策略。

红点预拉取到的内容被用户使用的概率比较大,旁路预拉取可以优化多tab浏览时用户切tab的体验,曝光预拉取与定时预拉取相结合,解决某些App厂商在某些时间点统一杀App进程导致后台在某个时间点访问点突增的问题。

在红点撤销、热门红点过期、新增热门红点时候丢弃之前预加载的内容,但在有红点的背景下触发 旁路、曝光或定时 预拉取时,要带上相应的红点信息。

b.预拉取要做假耗时

这里需要注意一个交互上的细节,预拉取的初衷是降低拉取的等待耗时,但如果将等待耗时降低到了0秒,可能会给用户一种并没有拉取成功,而是展示了历史占位的错觉。

所以即使客户端已经进行了内容预拉取,在用户触发加载时也要等待0.5s后再给用户展示数据,当然这0.5s是个经验值,实际工程中可以通过实验进行配置,找到一个既让用户感受到加载的过程,又能尽可能多的降低用户等待焦虑的时间点。

c.在预拉取方案下,所有的网络请求都应该设计成串行的

看到这里,你可能会发现采用预拉取会有一个风险点:

预拉取的请求(标记为预拉取A) 和 用户手动刷新的请求(标记为手动拉取B) 同时请求了服务器,那么用户到底应该展示哪个内容?

这里有两个方案:

  • 用户触发手动拉取B时,主动取消掉上一次的预拉取A,用户展示的内容以手动拉取B为准;

  • 用户触发手动拉取B时,这时发现预拉取A已经在请求服务器内容了,那么手动拉取B以预拉取A返回的数据为准。

附:实际上并发请求的后果比展示哪个内容更严重,并发请求甚至会导致数据丢失,或下发重复数据等问题。

08

预拉取存在的问题

通过上面的预拉取方案,实际过程中会发现两个问题:

  • 高并发,后台服务器成本高

  • 红点频率推送高的产品,经常会在上一个红点预拉取内容还未消费前,就被新的红点给覆盖了,预拉取存在浪费的情况

所以我们可不可以在减少预拉取频率的基础上,还能提高预拉取内容的使用率呢?答案是可行的,可以将人工智能和预拉取融合。

AI与预拉取

在展开讲解AI与预拉取策略之前,我们先做几个用户使用习惯的合理假设:

假设一:不同用户对不同的红点样式刺激不同,部分用户有着强烈查看特定红点内容的冲动

假设二:不同用户使用产品的频率不同

假设三:不同用户有着不同的高频使用产品的时间段,每个用户有着自己高频使用产品的特定时间段

a.根据用户画像触发预拉取

根据假设一,A用户可能对某个明星发的内容红点比较好奇,B用户可能对自己爱慕的人发新内容的红点比较冲动,千人前面,每个人对不同红点代表的含义查看冲动不同。可以通过建立模型来刻画用户感兴趣内容的用户画像,只针对用户感兴趣的消息红点触发预拉取,且可以提升这类红点的优先级,在不影响红点本身体系的情况下,让这类红点尽可能长的存在于用户界面上。

b.使用频率

根据假设二,有部分用户可能一直都接受到各种类型的消息红点,但始终没有对这类红点进行过消费,所以针对这类用户可以适当的进行红点惩罚,比如20分钟内不再推红点,又或者降低红点触发预拉取的频率,只针对用户感兴趣的红点触发预拉取,当用户频率和画像越来越全面时,再动态调整预拉取策略。

c.使用时间段

根据假设三,不同用户的使用时段可能不同,比如A用户上班时间较长,可能只会在晚上11点-12点期间进行内容消费,白天大部分时间即使收到了红点也没有时间去查看,通过建立统计模型明确用户高频使用时长,在这段时间段内提升用户预拉取的触发频率。


相关问题解释

红点预拉取

问题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内容。

曝光预拉取

问题1:如果客户端采取曝光预拉取的策略,从访问流量上考虑,服务器需要注意什么问题呢?

答:早上8、9点是用户起床的高峰期,但这段时间可能公司还没有开始上班,针对这段时间用户访问的峰值要提前进行监控,防止出现服务器宕机事故。

定时预拉取

问题1:以微信这样的产品为例,如果打算对视频号采取定时预拉取(比如每10分钟就对视频号内容进行预拉取),会不会有问题?

答:会有问题,微信主打即时通讯的产品,通讯才是最高频的使用场景。如果在微信打开期间都定时做视频号的内容预拉取,预拉取的内容被消费的几率不大,且可能会对服务器产生不必要的请求。

问题2:采取定时预拉取,用户首次启动app时(也即0分钟时),是否要进行预拉取?

答:有些安卓机出于性能考虑,会在某个时间点强杀所有app,所以在这种情况下所有用户重新打开app,对服务器的预拉取访问会出现一个突刺,而且用户打开app,实际上并不一定是要访问预拉取的内容,所以不建议在首次启动app时就直接去进行预拉取。




全部评论

(2) 回帖
加载中...
话题 回帖

推荐话题

相关热帖

近期精华帖

热门推荐