小程序购物车卡顿的处理

问题现象

用户小程序端进入购物车页面,购物车列表内容需要很长时间才能刷出,并且刷新过程中切换也很卡顿。

问题排查及分析
网速问题

同样的网速情况下,商品查询列表等接口并不慢,多人多部手机验证该可能性可排除。

接口速度

这个分两个来讲
一个是同样的接口,在其他类型终端上并不慢
第二个就是检查了前后端代码,并无针对于小程序端的条件编译代码。
该可能性可排除

前端加载数据后渲染慢
  • 经过漫长的二分法删代码排除后,效果不明显。页面处理速度基本一致。
  • 考虑是因为swipe组件的问题,尝试换成最基础的view做渲染,同样效果不明显。
峰回路转

要说一下的是,其实我在调试过程中模拟器其实渲染的也并不是很慢,这个是相对来说的,因为我访问其他页面的时候速度也比较慢,当时并没有在意。现在想想一切归结于“电脑卡“
在测试过程中,几次我已经认为问题已经处理完了。后面发现原因是体验版的小程序接口地址指向的是release环境。这就是问题所在。
当接口指向release时购物车加载正常,当指向uat或prod时不正常。

确认问题

上面说的接口指向release时不卡,指向prod和uat时就巨卡。相同的前端代码

接口差异

各个环境后端接口的差异其实也很小,毕竟代码都是一样的。

  • 考虑网络转发上面的因素
    release环境是使用的boot单体应用的方式部署的,外围使用的是nginx做的转发,内部使用的是dubbo直连的方式做的rpc调用
    uat使用的是k8s做的容器化部署,外围使用的ingress七层负载转发至Service,然后再转发到Deployment的方式,内部使用的dubbo通过zookeeper作为注册中心做rpc调用。
    prod在uat的基础上做了Waf控制。
    所以实际上可能出现问题的也就是 nginx 跟 ingress 的区别。
    但是ingress 全称是 ingress-nginx 啊, 说他们有区别也很不合理啊。

  • http请求本身的问题
    前面已经排除了后端接口可能出现问题,这一块也没有用到缓存等其他中间件。所以这里主要研究了一下前端的代码。
    我们前端使用的请求是异步的,为了等待请求返回结果做进一步处理。这里面就涉及几个概念:async/await,Promise。
    async 顾名思义,就是异步的意思, 看上去是一个异步标识,就是告诉我们这个函数中有异步执行的代码。用它标识的方法其实返回的是一个Promise。就算你不写, 直接return 个任何值会封装一下,让你return的东西出现在一个Promise的resolve() 。
    await 就是等待 async执行完,才会执行后面的东西, 等待的东西是异步的,它就会阻塞当前代码。
    Promise嘛,简单来讲就是一个对象,包含各种东西的对象。自带了很多东西,方便函数式编程。额 有一篇专门讲函数式编程哈。这个东西用的地方太多,应该跟它没关系。
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZflHUvFZ-1634096581175)(evernotecid://60A755FD-3AFA-4157-A2D9-274A2FBBF06D/appyinxiangcom/22938263/ENResource/p529)][外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-t3GkxEvl-1634096581177)(evernotecid://60A755FD-3AFA-4157-A2D9-274A2FBBF06D/appyinxiangcom/22938263/ENResource/p530)]

这个能看出来才100毫秒,各个环境都差不多。当然我还花了不少时间去搞http.js里的东西,但总的来说这个就是没有问题的。

数据差异

其实到进行到这一步的时候就会有感觉,上面进行的所有操作其实意义不大了。讲真这几个环境除了数据没啥大的区别。
所以我使用了release环境连接了uat的数据库。果然,复现了。

那现在就是比较两边的数据有什么不一样的了。
首先比较系统设置
同步设置了release跟uat的所有能够配置的地方。但效果还是一样的。这边没能确定问题。
那就是接口数据本身的问题了。
尝试取消网络请求,直接使用json数据渲染
在这里插入图片描述

果然json数据不一样,渲染速度也是不一样的。下面就是比较json的差异。

  • 结构差异
    细致比较下来json结构一模一样

  • 值差异
    采用二分法一步步最终确认了有问题的是购物车id。
    在这里插入图片描述

    细致尝试下,当id值过大时就会渲染慢。release上的数据量小,所以渲染看不出问题。

到这,确认了是因为id导致了慢。

找了一下这个id在代码中有哪些地方用了,发现它的用处是给购物车行渲染“收藏”和“删除”按钮的。
在view上有绑定,在loaddata时需要判断显示商品是否为“已收藏”。
在这里插入图片描述

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OLdjhsdn-1634096581185)(evernotecid://60A755FD-3AFA-4157-A2D9-274A2FBBF06D/appyinxiangcom/22938263/ENResource/p534)]

分别删除这两处地方比较,发现只用两处同时删除时,渲染才能正常。
那就开始断点查看方法里到底做了什么。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BBoXxFXo-1634096581186)(evernotecid://60A755FD-3AFA-4157-A2D9-274A2FBBF06D/appyinxiangcom/22938263/ENResource/p535)]

这边可以看出来,在给optionsList赋值后,它的整体结构变了。这为什么?
进一步查看
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cYczIprO-1634096581187)(evernotecid://60A755FD-3AFA-4157-A2D9-274A2FBBF06D/appyinxiangcom/22938263/ENResource/p536)]

开始时optionsList的类型为数组
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EClSfZcx-1634096581188)(evernotecid://60A755FD-3AFA-4157-A2D9-274A2FBBF06D/appyinxiangcom/22938263/ENResource/p537)]

赋值后变为了对象,并且有一个很大的length, 比id多1
这就很有意思了。
仔细看optionsList在初始化时给他定义的是一个数组
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5r4ESRdv-1634096581189)(evernotecid://60A755FD-3AFA-4157-A2D9-274A2FBBF06D/appyinxiangcom/22938263/ENResource/p538)]
在方法中的使用方式为optionsList[item.id] 这种取值方式其实在js中可能分为两种情况,一个是数组根据下标取值,另一个是对象根据属性名称取值。这个是数组,也就是 optionsList[2436523453245] 意思为数组下标为2436523453245的值。
做个简单的demo
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-huKH7XKB-1634096581190)(evernotecid://60A755FD-3AFA-4157-A2D9-274A2FBBF06D/appyinxiangcom/22938263/ENResource/p539)]

这边可以看出,其实数组中只有一个值,但是长度却是101,空间已经开出来了,只是没值而已。
修改也很简单,初始化时将它定义为对象就可以了。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-prHZfg1y-1634096581191)(evernotecid://60A755FD-3AFA-4157-A2D9-274A2FBBF06D/appyinxiangcom/22938263/ENResource/p540)]

分析问题

上面已经说了只要初始化时将optionsList 设置为对象就可以了,那为什么呢?为什么h5和app是好的,小程序就不行呢。
这边要从小程序的加载机制来说
小程序框架系统分为两部分:逻辑层(App Service)和 视图层(View)。小程序提供了自己的视图层描述语言 WXML 和 WXSS,以及基于 JavaScript 的逻辑层框架,并在视图层与逻辑层间提供了数据传输和事件系统,让开发者能够专注于数据与逻辑。
简单来说就是,小程序加载是微信内核其实干了两件事,一件事是渲染试图,将标记语言解析到Dom树上。另一件事是加载数据,执行我们写的那些钩子。这个在官方文档上都有。
逻辑层调用setData方法将数据传递到视图层。它是会阻塞进程的。这个就有问题了。
setData方法是通过消息的方式去实现的。其实传递的是一个字符串。逻辑层会将数据转换成字符串,然后视图再去解析这个字符串。
做个小demo
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xrhL2Nos-1634096581191)(evernotecid://60A755FD-3AFA-4157-A2D9-274A2FBBF06D/appyinxiangcom/22938263/ENResource/p542)]

可以看出来,其实data数据本身是不大的,但是经过这一转换其实就很大了,加上这一步又是进程阻塞的。效果就显而易见了。

总结

前前后后这个问题拖了也有两个月了,我去解决这个问题也大概花了一个星期的时间。无论暴躁、崩溃啥的,总归这个问题是解决了。总结起来还是有一些可以改进的地方。

  1. 首先应该想到的就是数据问题,遇到这种问题就应该第一时间把正式环境的数据导到测试环境再尝试复现。而不是先在想外围的问题,走了不少弯路。
  2. 关注模拟器控制台的警告
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-r0YMNBY6-1634096581193)(evernotecid://60A755FD-3AFA-4157-A2D9-274A2FBBF06D/appyinxiangcom/22938263/ENResource/p543)]

其实这个警报就是上面分析出的那个问题,但是在不了解机制的时候,本能的以为是下面好物推荐的报的错。其实深究一下应该是会加快我们解决问题的速度

愿 世界和平

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值