利用链表数据结构优化页面渲染
需求及所遇问题
页面数据的渲染优化有很多种方法,如果遇到列表数据很多的情况下,通常用的方法就是进行分页请求,但有时后台并不会将数据进行分页加载,把数据全部返回给了前端,这时前端有没有方法去优化渲染呢? 如图: 需求:点击左侧导航,有子列表右侧实现相应滚动,没有子列表,实现请求跳转页面;滑动右侧,左侧导航active相应改变
数据结构:大概如下:
data = [
{id:1, children:[{id: 11, name: '', img: ''}]},
{id: 2},
{id:3, children:[{id:41, name:''}],
{id:4}
]
问题:后台返回的数据可能会是超100,甚至200条数据,造成页面渲染慢,怎么优化?
基于项目的需求,以及数据的形式,因为后台不进行分页返回,那么只能是前端优化,可是如何优化呢?
既然是因为渲染数据过多造成的渲染问题,那么就进行首屏优化,这个简单,我们通过截取数组,可以先渲染数组前面20条。但另一个问题来了,怎么在滚动或者点击的时候加载相应的数据呢?
滚动还简单些,按顺序将数组push上去。但另一个左侧点击,渲染相关的数据,并且当active类的子列表数组很少时,我们还需要显示离active类相邻的前后有子类的数据,问题是每个大分类不一定有子列表,而且当前active的前后分类的数据也是不一定就有子数据。显然,我们没法通过数组的索引知道当前active分类与其相邻的最近有子列表的大类是哪个。当然,每次都去循环获取,也可以得到,但显然这种方式不太友好。
我们需要另一种数据存储结构,这个数据结构能让我们拿到每个单项,都能知道它前后有子列表的大类是哪个。这时,链表的数据结构就可以解决这个问题,让每个单项之间具有联系。
什么是链表
数组的子项联系,来自于索引,它们的之间的关系是有序的,但链表是一种非顺序的存储结构,各项之间的联系是通过指针的链接顺序来实现。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。
举个例子,甲乙丙丁四人,各自都不知道自己在队伍里排几号,但是甲知道排在他前面的是乙,排在他后面的是丁,丙知道排在他前面的是丁,没有人排在他后面,那么我们很容易就可以知道他们的顺序是乙——甲——丁——丙。这个就是链表的存储数据结构,我们可以通过单项的数据找到它前后的联系,进而一项一项串起来。
如何设计链表
链表数据结构的基本思路:pre代表前一项的指针,next表示后一项的指针。显然,首项,没有前一项,用pre为null表示,尾项,没有后一项,用next为null表示
我们的需求是记录每个有children前后的联系,实现思路大概如下,代码实现:
let pre = null;
let next = null;
let dataObj = {}
data.forEach((item, index)=>{
if(item.children && item.children.length > 0){
if(index===data.length-1) {
next = null
} else {
next = data[index+1].id
}
item.next = next
item.pre = pre
pre = item.id
dataObj[item.id] = item
}
})
这里用对象存储是为了在每次点击获取单个数据项时,不必进行循环获取
滚动添加数据
但滚轮向下滚动时,进行添加数据渲染,基本思路,根据当前active大类(有children)的id,进行判断:
- 当前active大类还有children项未添加显示,继续添加
- 当前active大类children项已全部添加完,需添加next大类的children
- 点击选中左侧,当前active大类children项已全部添加完,next大类的children也全部添加完,但页面还有空间显示,需添加pre大类的children
代码这里就不写了,但这里我们可以看到,通过链表,我们可以减少循环遍历,很快就能知道单项的前后联系,实现快速查找的过程。
结语
页面优化的方式有很多,当我们需要从数据的单项知道某种联系,但是数组的索引无法满足的话,可以考虑一下用链表的形式,可以更加快速有效的获取到数据。另外,本文写的比较简略,仅提供思路和方法参考,详细的建议可以去查找资料。
上一篇: 逻辑推理--双方轮流拿球,谁拿到最后一个球谁获胜!
下一篇: 为什么大家都在使用 WebRTC?
推荐阅读
-
利用链表数据结构优化页面渲染
-
利用 Vue 3 组合式 API 优化 Uni-app 基本页面功能
-
在React和Vue中,我们是如何玩转router的? - 使用HTML5 History API,React Router利用pushState和replaceState方法在不刷新页面的情况下管理导航历史。它像这样工作: 1. 当URL发生变化时,React Router悄悄地“监听”浏览器地址栏的改动,主要通过popstate事件来察觉url更改。 2. 随着URL的变化,Router会对照预先设定好的JavaScript路由配置对象,依据一套规则找出与当前URL匹配的路径。 3. 一旦找到合适的路线,React Router就会如魔法般地渲染相应的组件到网页上,从而实现了页面内容的实时更新。让我们来看一个React Router实际运用的例子。
-
✍️性能优化之图片加载篇——让页面图片渲染更丝滑????