前端大数据分流处理
一、前言
今天我们来聊聊大数据场景下,数据处理的问题。
众所周知,数据从数据库到用户眼前,一共会经过好几道关卡: 网络下载,前端逻辑处理,页面渲染。
这里按用时排行,那肯定是页面渲染最久,网络下载其次,前端逻辑处理最快。
我们今天做文章的部分也就是页面渲染这一块,大数据下,页面渲染很费时间的,同时渲染会导致页面卡顿时间较长,如果能错开,至少不会让页面长时间空屏,从而影响用户体验感。
二、 场景分析
1、具体场景
后端返回近w条数据,每一条数据都需要展现在地图页面窗口上。
(只加载视图的懒加载做法基本无了,还不允许用大数据聚合类,纯靠marker,就是有这种奇葩的要求,就事论事。)
2、常规做法
一开始我就没当回事,接口返回数据后,直接一个forEach循环,同时创建了近w个marker点,页面直接卡住,加上这个实时性又稍高,所以页面还没加载完,新一轮的近w条数据又冲击了过来,结果可想而知,页面直接崩溃了。
偶尔有不崩溃的时候,也是卡顿完之后,一下子就出来近w个marker,十分突兀。
3、分流处理
既然一次性处理近w条会直接卡顿,那我分开处理,有一定的时间间隔,是不是浏览器的处理能力就能跟得上呢?抱着这个想法,说干就干。
(1)拆分函数
源数据是一个有近w条数据的数组,那就按10条拆分,那就能变成一个长度为1000的二维数组【[10个元素],[10个元素],[10个元素],...】,当然可以根据需求和性能,对这个数量进行修改。
// 拆分函数
averageFn(arr, num = 10) {
let i = 0
let result = []
while (i < arr.length) {
result.push(arr.slice(i, i + num)) // 一次截取10个用于分堆
i = i + num // 这10个截取完,再准备截取下10个 num默认为10
}
return result
},
(2)递归调用,分批次渲染函数
这里我们选用递归+requestAnimationFrame动画帧的方式来分批次渲染。(也可以for二重循环+定时器来做,不过性能上可能稍差一些,定时器性能影响多点)。
基本上确定好递归的结束条件,然后我们就是在对应的地方,写入我们的具体业务逻辑即可。
// 递归调用的部分
// 定义一个函数,专门用来做赋值渲染(使用二维数组中的每一项)
use2DArrItem(page) {
// 1. 从第一项,取到最后一项
if (page > this.roadLineArrayObjectAvg.length - 1) {
console.log("每一项都获取完了")
return
}
// 2. 使用请求动画帧的方式
requestAnimationFrame(() => {
// 3. 对每个小数组进行逻辑处理 // 此处替换对应逻辑
this.roadLineArrayObjectAvg[page].forEach(item => {
调用地图api,添加marker点
})
}
// 4. 这一项搞定,继续下一项
page = page + 1
// 5. 直至完毕(递归调用,注意结束条件,为page>数组长度-1)
this.use2DArrItem(page)
})
}
(3)拆分数据、调用函数
调用拆分函数对源数据进行拆分,得到我们需要的二维数组,随机调用我们的分批次函数,依次渲染。
this.roadLineArrayObjectAvg = this.averageFn(源数据res.data, 10)
this.use2DArrItem(0)
(4)效果
现在页面能够正常响应了,marker基本上10个点成片成片的叠加,整体就像是按区域加载,观感上好了不少。
页面也没有长时间的卡顿。
三、小结
处理大数据的方法有很多,本文只是举了其中一种,相信掘友们有更好的方式可以来应对这种情况。
ps: 我是地霊殿__三無,希望能帮到你。
转载自:https://juejin.cn/post/7246935481616072759