这一次,我将卡顿彻底干掉了

做需求的过程中,不能死扣住一种实现方式,也许你发现你的优化之路已经到了尽头,但极有可能这只是一个开始

话说,我的app有着这样的一个页面:遇见未来的你。没错,它是我这个app的首页,所以,我无时无刻不在想着,怎么样保证这个页面,动画流程,滑动流畅,等等等等,总之,就是要保证流畅!

要了解这个页面为什么要优化,为什么做了一些优化,还先要说一下我们这个页面的业务:

以上是我们最初的想法,很显然,1秒钟就被否定了,uid集合也许很多,比如100多个,那么批量查询出的所有的用户这个数据量明显很大,存在两个很明显的弊端:

1、用户的流量极大浪费,后面88个我不care,你浪费我的流量,所以我卸载你的app。

2、失败率!没错,数据量大,一个显而易见的问题是接口失败率会有所上升。

3、且不说后台压力的问题。。

于是乎:

于是,前后台也达成了一致,因为以上问题都解决了,所以就这个方案了!

然而,身为前端的我缺遇到了一些其他的问题。

这个一个页面如何做,有没有原生的控件可以实现这样的效果,走出第一步尝试,我选择了ViewPager这条不归路,可以看到,like效果还是不错的。

爱情就像龙转风一阵。

 

然而,看下滑动卡片的效果,这个才是本文的重点:

可以看到,大部分时候滑动是不卡的,但是总有那么一个点(实际上是一段一段),是会卡一下的!因为时间的关系,之前的优化到了这里就告一段落,留下了一个小小的瑕疵。

那么,这是为什么?

这就要归功于我们的分批加载了,假如说,后台此次返回了100个uid,如果,前端每次加载20个,那么,需要5次才可以加载完,那么,首屏的加载实际上是在fragment(这个页放在fragment中)的onCreateView的时候就去加载,用户感知不到,或者说感觉不那么明显。

但是!

当到达第一分批加载的时候,也就是去拉取20-40条user信息的时候,就会卡你一下,那么为什么,因为你拿到数据塞给pagerAdapter之后,你需要调用一次notifyDataSetChange,如果你企图使用其他方式(反正我试过),那么,很抱歉,你将会遇到这位大爷:

java.lang.IllegalStateException: The application's PagerAdapter changed the adapter's contents without calling PagerAdapter#notifyDataSetChanged!

 那么,一定有人也不服气,比如说:这个卡顿也不一定是因为这个notifyDataSetChange带来的吧,会不会是UI有某些耗时的操作导致的呢?别急,我们问问traceView呗:

很抱歉,因为多次的优化,所以这里只能在第48位找到我们包名下面的一个耗时户,然而这里的inflate的内部的操作依然已经无法优化了,还记得上次,我们已经将占位资源全部都干掉了吗?然后,降低布局层级,只用一个RelativeLayout写出了这个布局,那么这里既然已经无法再做优化。

我们试试看看往上追踪,看谁调用了这个方法,能不能够有所突破,看看到底是不是notifyDataSetChange呢?

第一次:

。。。第N次:

然后,最后确认了,真的是notifyDataSetChange无疑,如果说不分批,即一次性加载,viewpager这个方案也就不不存在这个问题了。

那么,既然,我们找到元凶,那么该怎么办呢?

既然,是inflate操作这么耗时,而分批查询到数据添加到pagerAdapter中又不得不notifyDataSetChange一下,如果不做inflate操作,是否问题就解决了呢?

很容易,想到了RecyclerView,那么,何必不用RecyclerView去做一个类似的效果呢?

说干就干吧,花了一天的时间,重构这里的代码?

 private void addUserList(List<User> userList) {
        if (userList != null && userList.size() > 0) {
            int oldCount = mostMatchAdapter.getItemCount();
            mostMatchAdapter.addUserList(userList);
            int newCount = mostMatchAdapter.getItemCount();
            setAdapterState();
            mostMatchAdapter.notifyItemRangeInserted(oldCount, newCount);
        }

    }

最终,我们分批加载之后,不在是notifyDataSetChange了,而是现在的notifyItemRangeInserted。众所周知,RecycledViewPool lets you share Views between multiple RecyclerViews.因此,inflate耗时的问题,解决了。 

好吧,看看效果吧:

此时,依然是分批加载的背后,体现到前端的展示效果,缺已然没有了卡顿的存在。可以看到帧率大多在60以下,不在有很多尖锐的矩状出现了,滑动明显流畅了很多。

总结:在做需求的过程中,一开始难免会有方案的选择,当时的选择不一定是对的,当遇到问题提爬不过去了,是否考虑使用之前想到过的其他方案呢?

 


 

 

 

关于腾讯WeTest (wetest.qq.com)

 

腾讯WeTest是腾讯游戏官方推出的一站式游戏测试平台,用十年腾讯游戏测试经验帮助广大开发者对游戏开发全生命周期进行质量保障。腾讯WeTest提供:适配兼容测试;云端真机调试;安全测试;耗电量测试;服务器性能测试;舆情监控等服务。

 

最新文章
1客户案例研究:专家安全扫描,守护金融银行小程序安全和私密性 WeTest私有化部署的定制扫描平台让金融银行客户能无成本接入扫描系统并迅速上手使用。客户能方便快捷地根据定制手册进行自助扫描,根据生成的扫描报告,详细洞察漏洞,快速识别并准确定位问题根源。
2客户案例研究:专家渗透测试,洞察电子商务小程序重大交易漏洞 通过WeTest渗透测试服务,某知名零售公司旗下的在线购物类小程序中发现了8处安全风险,我们的安全专家为客户提供了详细的漏洞报告,提供了较为清晰完整的安全加固方案。在回归测试中,中危以上风险均被解决。
3自查小程序4大安全隐患!文末免费赠送小程序安全扫描专业版! 腾讯WeTest现面向小程序开发者开放免费申请使用小程序安全扫描专业版,助您提前发现全面的安全漏洞。扫描文中问卷二维码或点击问卷链接,即可报名参与免费领取活动。
4浅谈渗透测试服务在泛互行业带来的价值 在泛互联网行业中,渗透测试服务对于保障企业的网络安全至关重要。
5云手机卡顿/无特定设备/商店登录受限怎么办?WeTest专有云帮您解决! 公有云满足了大量小微企业、个人的测试需求;随着客户深入使用,也遇到了一系列新问题。本篇将对几个常见问题予以解答
购买
客服
反馈