请求速度快的时候出现loading,而较快时不出现
发布于 2018-07-26 00:37 阅读数 911
本文必须得到作者授权后,方可转载,摘要引流随意。
By 依韵 , From https://blog.cdswyda.com/post/show-loading-when-slow
请求速度快的时候出现loading,而较快时不出现
这是两年前我刚入职不久后收到的一个需求,恰逢近日有人问起,特此记录分享。
需求场景描述
通常在发起请求加载数据时,会在页面上出现 loading 的动画,让用户知道正在加载数据,而不是网站出了什么问题,反正是挺常见且常用的手段。
通常的 loading 效果都是有一些动画的,如构造近似的进度条、转圈圈等,通常这个loading效果在最终移除的时候会有一个渐隐的效果,这就导致了一个“弊端” —— 给用户看起来,加了 loading 效果会比有没有的情况下慢。
当然作为开发者的我们都知道,这个实际并没有影响,但是不得不承认就肉眼来看,在请求相对较快的情况下,出现loading的视觉效果确实比没有的情况下慢。慢一些的情况下,当然还是有 loading 更加人性化。
就这样一个需求诞生了 —— 在请求快的情况下出现loading,而较快的情况下不会出现loading。
实现过程
当时刚入前端,基本还是小白状态。 收到这个需求,心里简直是万马奔腾呀。这不是异想天开吗?我怎么能在请求发起前就知道这个请求需要多久,这完全、根本、绝对不可能嘛。
P.S. 当时还处于小白状态,不知道可以寻求万能网络的帮助。
但是需求是领导提的,不是产品,不是客户,没有怼回去的可能。硬着头皮,只能是做。
嗯? js 里面不是有个 setTimeout
的东西吗,这货可以让一段代码在指定时间之后进行,那我直接让在请求前迟延一段时间出现遮罩不就行了吗?
实现代码非常简单,如下:
var loadingTimer = setTimeout(function () {
epoint.showLoading();
}, 200);
$.ajax({
url: 'abc.xyz'
}).always(function () {
clearTimeout(loadingTimer);
epoint.hideLoading();
});
简单到不可思议吧? 请求发起前使用定时器迟延一段时间出现 loading ,在请求完成时清除定时器,并隐藏 loading 。简单明了,效果达成。
这个需求就这么完成了,但是自己心里一直觉得这需求不合理,实现也根本是凑出来的,并非正途。(这里其实有点问题,后文会提到)
直到去年在阿里D2大会上,看到淘宝也用这种方案,请求快的时候没有 loading ,而较慢时才会出现 loading 。
这么看来:需求不是合理呀,还是要相信——存在即合理呀。
还有也不宜“妄自菲薄,引喻失义” 呀,毕竟自己想出来的东西(或许并非首创,但当时确实是自己想出来的,没有其他参考)也和大厂采用的方案相吻合。
弊端和注意问题
虽然(我的)这种方案和大厂的如出一辙,但是不得不承认,其毕竟是投机做法。原谅我的个人偏见,总觉得使用 setTimeout
来凑出各种效果都不是正途。包括我们还采用的一种情况:按钮上既有单机事件,又有双击事件,但是要求双击时不能触发单击的处理函数,方案则是单击事件中执行的代码使用 setTimeout
处理,双击事件中清除单击事件中的定时器再执行自身的代码。虽然效果完美实现,但 我 仍 然 觉 得 —— 这并非正途。
投机自然是有代价的,这里也不例外。有一个很明显的副作用。
注意到上面代码中迟延出现遮罩的时间了吗? 我给出的示例代码中就是那个 200
。
设想以下情况:如果绝大多数请求的响应时间都分布在 200ms 左右会出现什么情况? 我替你描述吧~ loading 很晚才出来,而且一出来马上就没了,不管有没有渐出或者渐隐的动画,如果出现这种情况,效果毕竟大打折扣,还不如直接有或者直接没有呢。
所以此处问题的核心在于,关于请求快慢的时间阈值的界定。我厂所使用的快慢阈值是 200ms
,而淘宝毕竟大厂,优化好,阈值是 100ms
。 这个时间阈值决不可照搬硬套,请务必统计使用场景下请求的响应时间,务必避开时间集中的值。
当然不管怎么调整这个请求快慢的阈值都不可能完全避免那个 loading 可能为一闪而逝的情况,或许这就是投机上注定要承担的风险吧。但是选定合理的阈值,即可提高体验、又能尽可能地减低不良情况的出现概率,何乐而不为呢?
不错的经验
那请问现在您对实现中需求的 loading 有完美的解决方案了吗
@大桔子 目前依旧是沿用这个方案。 针对项目情况,统计一下请求需要的时间,设定合理的阈值就好。