欢迎光临散文网 会员登陆 & 注册

后端一次性返回 10万 条数据的几 种应对方案

2023-04-24 10:41 作者:要宠你上天  | 我要投稿


    问题描述

    • 面试官:后端一次性返回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,看名字就知道做的是表格相关的业务。其中就包括虚拟列表。

vue2vue3版本都支持,性能比较好,官方说:**虚拟滚动(最大可以支撑 5w 列、30w 行)**

强大!

官方网站地址:vxetable.cn/v3/#/table/…

安装使用代码

注意安装版本,笔者使用的版本如下:

cnpm i xe-utils vxe-table@3.6.11 \--save

「main.js」

代码方面也很简单,如下:

方案七: 开启多线程Web Worker进行操作

本案例中,使用Web Worker另外开启一个线程去操作代码逻辑,收益并不是特别大(假如使用虚拟滚动列表插件的情况下)

不过也算是一个拓展的思路吧,面试的时候,倒是可以说一说,提一提。

后端一次性返回 10万 条数据的几 种应对方案的评论 (共 条)

分享到微博请遵守国家法律