如果被耗时任务拖累,可能是姿势不对

如果被耗时任务拖累,可能是姿势不对

在业务中,有时候需要处理一些相对耗时的事情,而且还有一些其他的逻辑还可能会依赖这个耗时任务。诚然,太久的耗时会对用户体验不好。

本文就自己在业务中的一次实践,从其中一个小角度来分享看法,纯属个人观点,如有纰漏之处,还望指教。

背景

我们的项目是Hybrid混合应用,页面运行在手机QQ(后续简称手Q)中。在我们的业务中,我们有个新上线的业务,进入页面A之后,需要根据用户的地理位置(可以用缓存)去跳转到新业务页面B(灰度)或者继续渲染页面A。

最正经的实现方案

很容易想到的最正(diao)经(si)的一种实现方案,就是先获得当前用户的地理位置,拿到地理位置之后,还要去调用后台CGI接口,获得当前用户处于的城市,然后再根据这个城市,判断是否应该跳转到特定的页面。

伪代码实现

使用伪代码表示如下:

// 调用手Q接口获取当前用户的地理位置,data中包含了经度和纬度
getLocation(function(data){
    // 调用CGI接口,获得当前的城市信息
    getCity(data, function(res){
        if(res.city=='深圳') {
            // 跳转到页面B
            jumpTo('pageB');
        } else {
            // 继续渲染页面A
            init();
        }
    });
});

你真不是来捣乱的吧

理论是美好的,但是...

  1. 客户端的 getLocation 接口去获取用户当前地理位置,其实是非常耗时的操作。经过多次测试,获取一次的耗时在 2s ~ 5s 左右,即便可以使用其缓存,也需要花费 200ms 以上,而且还很不稳定。要知道当时测试的环境是 wifi 下,而且测试机是比较新的配置中等的小米4。如果真实用户拿着一个配置不高的手机,然后在网络状况不好的场景下,我猜测耗时会更高。
  2. 除了客户端的接口会耗时之外,还需要调用一次后台CGI,由于这个CGI接口已经在现网运行过一段时间,从检测的数据来说,wifi下请求一次耗时大概在 50ms ~ 150ms 左右,如果在非wifi场景下,这个时间肯定会更耗时。
  3. webview本身初始化时间、js/css/img文件、其他CGI请求等的耗时等累积也在几百毫秒以上。

综上,如果用户第一次没有缓存的情况下,或者网络状况不好,或者他用的手机属于比较亲(di)民(duan)的那种,那么,当用户看着加载的菊花图一直转啊转,耳边不禁想起“跟着我左手右手一个慢动作,右手左手慢动作重播”时,我想应该没有多少人是会有耐心等待的。

进一步分析

上文讨论的最常规的方案显然会有体验的问题,怎么办?

需要时效性吗

对我们造成困扰的缘故,在于我们常会有一种程序员的思维(情怀),认为流程就是这样啊,这样才能够实现功能,而且是最精确最实时的。你看每次你进来我们的页面我们就对你进行一次判断,避免上一分钟你在城市A,下一分钟到了城市B会出问题。

没错,追求精确和完美并不是坏事,但这会付出时间成本,在这里而言,我们真的那么需要时效性吗?80% 以上的用户很少会在几小时或一天内会离开一座城市;即便离开了,看得到我们的新页面了,也没任何关系,更何况我们是在灰度,多几个人看到关系不大,以后迟早大家都看得到。

缓存地理位置

既然没有时效性的要求,要处理的业务也不是敏感,那么就缓存呗。且不是说缓存客户端的 getLocation 结果,而是直接缓存最后计算得到的城市名。

if (!existCity) {
    // 调用手Q接口获取当前用户的地理位置,data中包含了经度和纬度
    getLocation(function(data) {
        // 调用CGI接口,获得当前的城市信息
        getCity(data, function(res) {
            if (res.city == '深圳') {
                // 跳转到页面B
                jumpTo('pageB');
            } else {
                // 继续渲染页面A
                init();
            }
        });
    });
} else {
    // 继续渲染页面A
    init();
}

用户的第一次

即便我们可以缓存地理位置,那用户第一次进来没有缓存时,依然逃脱不了加载缓慢的命运。难道要告诉用户说“忍一忍,第一次都会痛苦的,下一次再来时你就会感到畅快了”?对用户的第一次不负责,用户可能就不会给你第二次了。

提前准备缓存

既然在用户要的时候无法满足他们的需求,那么,何不提前准备呢?比如在一个浪漫温馨你侬我侬的夜晚,气氛恰到好处,却发现缺少了“必要的东西”,这时候需要你大晚上下楼跑几条街的店里去贡献一点GDP,你会崩溃的。

回到我们说的场景,似乎也可以提前发一个版本,在这个版本中,增加一个小功能,就是在用户正常打开页面之后,再私下去获取到用户的位置,并放入到本地 localStorage 中缓存结果。等到真实版本发出之后,由于之前已经有缓存结果了,那么就省略了调用接口的过程,而换成了判断 localStorage 缓存了,这个性能立即就上来了。

先领劵,再享受优惠

提前准备缓存的办法理论上是行得通的,但麻烦啊,要新发版本,而且为了一小部分灰度的人,影响了大部分人的体验(新版本发了之后之前的离线包或js文件缓存就失效了,何况他们又享受不到新的业务,浪费),有点不值得。就比如“必要的东西”是准备了,但没机会使用,也就浪费了。

进一步分析,还可以有进一步的优化。简单而言,就是用户第一次进来时,全都展示原始的页面A后,后台开始获取城市信息,并打上缓存(发放优惠劵,但也不是所有人都发,比如乞丐之类的就忽略了);第二次之后再来时,有指定的缓存了就直接跳转到页面B了(凭借优惠券享受优惠)。实际上我们最终的方案就是这种。

最后的方案和总结

上面说到了我们最终的方案是“先领劵再享受优惠”的思路。其实这和离线包的机制是类似的,如果本地没有离线包,则返回线上的,同时手Q后台线程会去拉取离线包到本地;等第二次再来时,由于有了离线包,这时候就直接使用离线包的内容,提升了用户体验。

很罗嗦的记录了最近在某个业务中遇到的情况,我想表达的内容也比较简单,就是如果我们依赖了很耗时的业务时,可以换种思维,换种姿势,例如将同步处理修改为异步处理,或者思考其他的方式,来解决技术无法解决问题。很典型的还有我们常见的进度条或者菊花loading图,也是从另外的方面的努力,来“掩盖”耗时的问题,而耗时问题有时候是无法避免的。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏PPV课数据科学社区

如何用Python分析大数据(以Twitter数据挖掘为例)

大数据无处不在。在时下这个年代,不管你喜欢与否,在运营一个成功的商业的过程中都有可能会遇到它。 本教程将会简要介绍何谓大数据,无论你是尝试抓住时机的商人,抑或是...

7193
来自专栏web前端教室

如何从零开始,形成自己的模块化思维方式?

计算机这东西不是凭空出现的,它是为了解决一些实际的问题,有很多时候是对现实世界的模拟。遇到问题时,经常会有人说,要有大局观,要具体问题具体分析,也可以牵强的解释...

1052
来自专栏闰土大叔

为什么我不推荐你使用vue-cli创建脚手架?

最近在知乎看到一个问题,原问题如下: “ 很奇怪,为什么现在能找到自己手动创建vue脚手架的文章非常少,而且大家似乎对webpack4的热情并不高,对于想基于v...

46213
来自专栏Crossin的编程教室

我们一直谈论“写代码”,但你会“读代码”吗?

编程,又被称作“写代码”。这个说法有可能会带来一点点误解,让人觉得如何“写”是学习编程要解决的主要问题。但事实并非如此。尽管最终代码要在键盘上敲出来,但这个过程...

802
来自专栏服务端技术杂谈

重构系统的套路-写有组织的代码

如果一个项目经历了快速发展,势必在业务发展背后留下了一个很无序,结构混乱的代码,无序而混乱的代码势必造成很大的bug修复及扩展成本。 说到搭建系统都在谈论高并发...

31510
来自专栏腾讯移动品质中心TMQ的专栏

【腾讯TMQ】测试分析?就这么简单!

在软件测试过程中,以最小的成本将软件质量风险降至最低,这就是精准测试。宏观上,测试分析是响应精准测试的实践,贯穿整个测试过程,并对整个测试过程起指导作用。

3850
来自专栏沈唁志

详解Linux运维工程师必备技能

1762
来自专栏大数据

数据挖掘敲门砖-Python爬虫入门

WHAT ? 数据挖掘是一门综合的技术,随着Ai的兴起,在国内的需求日渐增大。 数据挖掘的职业方向通常有三个,顺便概要地提一下所需的技能(不仅于此) 数据分析方...

2299
来自专栏Android 开发者

[译] Android 的多摄像头支持

从 Android P 开始,添加了对逻辑多摄像头和 USB 摄像头的支持。这对 Android 开发者来说意味着什么?

1694
来自专栏CSDN技术头条

大规模数据集成: Linked Data

在本系列的前两篇文章(“ 使用 RDF 创建数据网络 ” 和 “ 使用 SPARQL 查询 RDF 数据 ”)中,您了解了资源描述框架和 SPARQL 协议和 ...

2108

扫码关注云+社区