项目重构前发现加载9万条商品需16秒,影响客户体验。团队参考竞品,决定分批请求和按需获取数据,优化前端请求逻辑和SQL查询,并利用后端多线程机制分块查询,同时瘦身返回体。最终请求时间降至1秒左右,百万条数据请求时间12秒左右。
项目终于要重构了,重构前需要对现有逻辑进行整理,其中发现一个必须要整改的点,加载所有商品,如果客户的商品达到9万条,则查询时间相当离谱,看截图
足足需要16s,也就是说客户在访问我们系统时,需要16s之后选商品才是全的。
既然发现了这个问题就要解决,那怎么解决呢?
领导给了我们一个好的idea,参考下竞品,看竞品是怎么做到的
ok,三人行,必有我师焉,搞起,把竞品的请求方式摸底下,还真别说,竞品的获取商品速度就是快,当然也和商品数量没有这么多有关
但是,竞品给了我们一个很好的思路:
获取商品不要一次返回所有数据,可以只返回单表数据,其他数据可以在需要展示时,按需获取
这个想法非常好,我们决定试一下,当然在试这个之前,我们还有一些其他优化可以做:
前端分批请求
不要一次把所有数据全请求完,充分利用浏览器的并发请求机制,浏览器发起的请求最大并发数量一般都是6~8个,所以可以一次请求一万条数据,请求9次,如此可以节省大量的时间,如下图可见,由之前的16s,已经降到5s左右,大跨度的提升
前端分批请求的逻辑也非常简单,对请求进行分页,然后把请求塞到数组里,再使用axios.all包一下,就就可以在回调中取得所有接口返回的数据了,顺序也是对的.
5s还是太久了,继续优化
优化sql,去掉关联查询,只保留商品表查询
查询商品接口仅做商品的查询,其他的如属性、规格、价格的都先不查询,可以在下拉弹窗出现时,滚动触底时补全数据,争取做到极简查询,通过这样一波优化,查询速度又得到了极大的提升,如下图可以看到速度提升到了2.6s左右,又快了一半
10万条数据,2.6s左右返回,虽然看着可以了,但是如果是百万商品呢,百万商品查询会不会又耗时很久呢,果不其然,百万商品耗时达到了23s多。
不行,继续优化,但是sql以及极简了,还能怎么优化呢,总不能换数据库吧,换数据库就不是这么简单的了,继续想
既然前端可以利用浏览器的并发机制分批次请求,那么后端是否也可以利用多线程机制分块请求呢?答案是可以的(一个后端大佬提供的想法,特此感谢)
后端分块查询数据库
前端一次请求一万条,后端再分成5个线程去连接数据库,每个线程查询2000条,请求完后再封装数据返回,
效果也是明显的,速度提升了有几百毫秒,忘记截图了,尴尬
优化后,请求时间已经无限接近我们的要求了,但还是有优化空间。
sql无法优化了,但是返回json可以优化,如果把返回体缩小了,是不是对请求时间也会降下来,于是后端同学立马行动,开始给返回体瘦身。
返回体瘦身
返回体瘦身又包括两个方面,第一删除无用的字段,只保留必须的6个字段,包括商品id、名称、编码、备注、规格、拼音,其他的就不返回了
第二方面,使用简写key值,前后端约定a:商品id,b:商品名称,c:商品编码 依次类推
返回后的数据长这样:
再看下效果,请求后时间有减少吗
请求时间终于降到了1s左右了,虽然会有一些上下浮动,但是有多次跑到了1s以内,基本算达成目标
再看下百万计的数据请求时间,12s左右,还可以了,毕竟百万计商品的客户屈指可数。
好了,这次优化就告一段落了,接口已经很快了,剩下的大头是前端的了,前端如何保证渲染10万条数据以及百万条数据不卡顿,也是一个挑战。
推荐阅读
您的鼓励与嘉奖将成为创作者们前进的动力,如果觉得本文还不错,可以给予作者创作打赏哦!
请选择打赏金币数 *