后端一次性返回 10万 条数据的几 种应对方案
面试官:后端一次性返回
10万条数据给你,如何处理?我:歪嘴一笑,
what the f**k!考察前端如何处理大量数据
考察候选人对于大量数据的性能优化
问题描述
问题考察点
看似无厘头的问题,实际上考查候选人「知识的广度和深度」,虽然在工作中这种情况很少遇到...
使用express创建一个十万条数据的接口
点击按钮,发请求,获取数据,渲染到表格上
html结构如下:
方案一: 直接渲染所有数据
如果请求到10万条数据直接渲染,页面会卡死的,很显然,这种方式是不可取的
方案二: 使用定时器分组分批分堆依次渲染(定时加载、分堆思想)
正常来说,十万条数据请求,需要2秒到10秒之间(有可能更长,取决于数据具体内容)
而这种方式就是,前端请求到10万条数据以后,先不着急渲染,先将10万条数据分堆分批次
比如一堆存放10条数据,那么十万条数据就有一万堆
使用定时器,一次渲染一堆,渲染一万次即可
这样做的话,页面就不会卡死了
分组分批分堆函数
我们先写一个函数,用于将10万条数据进行分堆
所谓的分堆其实「思想就是一次截取一定长度的数据」
比如一次截取10条数据,
头一次截取0~9,第二次截取10~19等固定长度的截取举例原来的数据是:
[1,2,3,4,5,6,7]假设我们分堆以后,一堆分3个,那么得到的结果就是二维数组了
即:
[ [1,2,3], [4,5,6], [7]]然后就遍历这个二维数组,得到每一项的数据,即为每一堆的数据
进而使用定时器一点点、一堆堆赋值渲染即可
分组分批分堆函数(一堆分10个)
创建定时器去依次赋值渲染
比如我们每隔一秒钟去赋值渲染一次
这种方式,相当于在很短的时间内创建许多个定时任务去处理,定时任务太多了,也耗费资源啊。
实际上,这种方式就有了大数据量分页的思想
方案三: 使用requestAnimationFrame替代定时器去做渲染
如果使用请求动画帧的话,就要修改一下代码写法了,前面的不变化,plan方法中的写法变一下即可,注意注释:
方案四: 搭配分页组件,前端进行分页(每页展示一堆,分堆思想)
这种方式,笔者曾经遇到过,当时的对应场景是数据量也就几十条,后端直接把几十条数据丢给前端,让前端去分页
后端不做分页的原因是。他当时临时有事情请假了,所以就前端去做分页了。
数据量大的情况下,这种方式,也是一种解决方案
思路也是在所有数据的基础上进行截取
简要代码如下:
方案五: 表格滚动触底加载(滚动到底,再加载一堆)
这里重点就是我们需要去判断,何时滚动条触底。判断方式主要有两种
scrollTop + clientHeight >= innerHeight或
new MutationObserver()去观测
目前市面上主流的一些插件的原理,大致是这两种。
笔者举例的这是,是使用的插件v-el-table-infinite-scroll,本质上这个插件是一个自定义指令。对应npm地址:www.npmjs.com/package/el-…
当然也有别的插件,如vue-scroller 等:一个意思,不赘述
注意,触底加载也是要分堆的,将发请求获取到的十万条数据,进行分好堆,然后每触底一次,就加载一堆即可
在el-table中使用el-table-infinite-scroll指令步骤
安装,注意版本号(区分vue2和vue3)
「cnpm install \--save el-table-infinite-scroll@1.0.10」
注册使用指令插件
因为是一个自定义指令,所以直接写在el-table标签上即可
案例代码
为了方便大家演示,这里笔者直接附上一个案例代码,注意看其中的「步骤」注释即可
方案六: 使用无限加载/虚拟列表进行展示
什么是虚拟列表?
所谓的虚拟列表实际上是「前端障眼法」的一种表现形式。
看到的好像所有的数据都渲染了,实际上只渲染「可视区域」的部分罢了
有点像我们看电影,我们看的话,是在一块电影屏幕上,一秒一秒的看(不停的放映)
但是实际上电影有俩小时,如果把两个小时的电影都铺开的话,那得需要多少块电影屏幕呢?
同理,如果10万条数据都渲染,那得需要多少dom节点元素呢?
所以我们只给用户看,他「当下能看到的」
如果用户要快进或快退(下拉滚动条或者上拉滚动条)
再把对应的内容呈现在电影屏幕上(呈现在可视区域内)
这样就实现了看着像是所有的dom元素每一条数据都有渲染的障眼法效果了
写一个简单的虚拟列表
这里笔者直接上代码,大家复制粘贴即可使用,笔者写了一些注释,以便于大家理解。
使用vxetable插件实现虚拟列表
如果不是列表,是table表格的话,笔者这里推荐一个好用的UI组件,vxetable,看名字就知道做的是表格相关的业务。其中就包括虚拟列表。
vue2和vue3版本都支持,性能比较好,官方说:**虚拟滚动(最大可以支撑 5w 列、30w 行)**
强大!
官方网站地址:vxetable.cn/v3/#/table/…
安装使用代码
注意安装版本,笔者使用的版本如下:
cnpm i xe-utils vxe-table@3.6.11 \--save
「main.js」
代码方面也很简单,如下:
方案七: 开启多线程Web Worker进行操作
本案例中,使用Web Worker另外开启一个线程去操作代码逻辑,收益并不是特别大(假如使用虚拟滚动列表插件的情况下)
不过也算是一个拓展的思路吧,面试的时候,倒是可以说一说,提一提。

