前端大数据渲染:虚拟列表、触底加载与分堆渲染方案

news/2024/9/25 3:09:14/

在这里插入图片描述

前言

针对表格展示数据,用户提出要求前端在表格下面有一展示多少条数据的选项,如果要求一次性展示10000条数据,如果直接染会造成页面的卡顿,渲染速度下降,内容展示慢,如果有操作,操作会卡顿

下面总结常见的几种大数据渲染方案

虚拟列表渲染

用虚拟列表的手段,即先对设置的可见区域内的数据进行演染,然后计算出鼠标滚动距离大约是滚动了多少项,通过动态的设置距离顶部的top值达到可见区域动态染数据不会卡顿的效果

<template><!-- 虚拟列表容器 --><divclass="virtualListWrap"ref="virtualListWrap":style="{ height: itemHeight * count + 'px' }"@scroll="handleScroll"><!-- 占位元素,高度为所有数据的总高度 --><divclass="placeholderDom":style="{ height: allListData.length * itemHeight + 'px' }"></div><!-- 实际显示的内容区域 --><div class="contentList" :style="{ top: topVal }"><!-- 循环渲染可见的数据项 --><divv-for="(item, index) in showListData":key="index"class="itemClass":style="{ height: itemHeight + 'px' }">{{ item.name }}</div></div><!-- 加载提示 --><div class="loadingBox" v-show="loading"><i class="el-icon-loading"></i>&nbsp;&nbsp;<span>loading...</span></div></div></template><script setup>import { ref, computed, onMounted } from 'vue';import axios from "axios";const allListData = ref([]); // 存储所有数据的数组const itemHeight = 40; // 每个列表项的高度(像素)const count = 10; // 一次显示的数据项数量const start = ref(0); // 当前可见区域的起始索引const end = ref(10); // 当前可见区域的结束索引const topVal = ref('0px'); // 内容区域的顶部偏移量const loading = ref(false); // 控制加载提示的显示const virtualListWrap = ref(null);// 计算当前应该显示的数据const showListData = computed(() => {return allListData.value.slice(start.value, end.value);});// 组件挂载后加载数据onMounted(async () => {loading.value = true;const res = await axios.get("http://124.223.69.156:3300/bigData");allListData.value = res.data.data;loading.value = false;});// 处理滚动事件const handleScroll = () => {// 获取滚动条位置const scrollTop = virtualListWrap.value.scrollTop;// 计算新的起始索引start.value = Math.floor(scrollTop / itemHeight);// 计算新的结束索引end.value = start.value + count;// 更新内容区域的顶部偏移量topVal.value = scrollTop + 'px';};</script><style scoped lang="less">// 虚拟列表容器盒子.virtualListWrap {box-sizing: border-box;width: 240px;border: solid 1px #000000;// 开启滚动条overflow-y: auto;// 开启相对定位position: relative;.contentList {width: 100%;height: auto;// 搭配使用绝对定位position: absolute;top: 0;left: 0;.itemClass {box-sizing: border-box;width: 100%;height: 40px;line-height: 40px;text-align: center;}// 奇偶行改一个颜色.itemClass:nth-child(even) {background: #c7edcc;}.itemClass:nth-child(odd) {background: pink;}}.loadingBox {position: absolute;top: 0;left: 0;right: 0;bottom: 0;width: 100%;height: 100%;background-color: rgba(255, 255, 255, 0.64);color: green;display: flex;justify-content: center;align-items: center;}}</style>

分堆渲染

通过将数据分成小块,只有当前可视区域的数据会被加载,这样避免了由于一次性加载大量数据而引发的性能瓶颈,从而减少了初始渲染时间,让用户可以快速看到界面。其次,分堆渲染有效降低了内存占用,因为系统只需保持当前可视部分的数据在内存中,尤其在处理大规模数据时,这种策略能显著提升应用的流畅度,防止因内存不足导致的崩溃或卡顿现象。此外,用户体验得到了极大的改善,用户在滚动或翻页时,新数据可以无缝加载,避免了传统分页方式中需要等待新页面加载的尴尬,让用户的操作更加自然和顺畅。

大数据一维数组通过while循环变成二维数组,然后借助requestanimationframeAPI对二维数组里面的每一堆进行分堆染达到染数据不卡顿的效果

<template>
<div v-if="activeName === 'first'"><el-buttonstyle="margin-bottom: 12px"size="small"type="primary":loading="loading"@click="plan">点击请求加载</el-button><el-tableheight="300":data="arr"borderstyle="width: 80%":header-cell-style="{height: '24px',lineHeight: '24px',color: '#606266',background: '#F5F5F5',fontWeight: 'bold',}"><el-table-column type="index" label="序"></el-table-column><el-table-column prop="id" label="ID"></el-table-column><el-table-column prop="name" label="名字"></el-table-column><el-table-column prop="value" label="对应值"></el-table-column></el-table></div>
</template>
<script>
import { ref } from 'vue';import axios from "axios";const arr = ref([]);const loading = ref(false);const averageFn = (arr) => {let i = 0;let res = [];while (i < arr.length) {res.push(arr.slice(i, i + 10));i = i + 10;}return res;};const plan = async () => {loading.value = true;const res = await axios.get('http://124.223.69.156:3300/bigData');loading.value = false;const resArr = averageFn(res.data.data);const useArr = (page) => {if (page > resArr.length - 1) {return;}requestAnimationFrame(() => {arr.value = [...arr.value, ...resArr[page]];page = page + 1;useArr(page);});};useArr(0);};</script><style lang="less" scoped>.bigDataBox {box-sizing: border-box;padding-right: 240px;}</style>

触底加载

无缝的交互方式让他们感觉更加自然,能够持续浏览内容。其次,触底加载能够有效管理数据的加载量,系统只在用户即将到达页面底部时才渲染新的数据,提高了加载速度

<template><!-- 触底加载 --><div class="box"><el-tablev-el-table-infinite-scroll="load"height="480":data="tableData"borderstyle="width: 80%"v-loading="loading"element-loading-text="稍后..."element-loading-spinner="el-icon-loading"element-loading-background="rgba(255, 255, 255, 0.5)":header-cell-style="{height: '24px',lineHeight: '24px',color: '#606266',background: '#F5F5F5',fontWeight: 'bold',}"><el-table-column type="index" label="序"></el-table-column><el-table-column prop="id" label="ID"></el-table-column><el-table-column prop="name" label="名字"></el-table-column>
<el-table-column prop="value" label="对应值"></el-table-column></el-table></div></template>KKKKKKKKKKKKKKKKKK  <script setup>import { ref, onMounted } from 'vue';import axios from "axios";KKKKKKKKKKKKKKKKfunction averageFn(arr) {let i = 0;let result = [];while (i < arr.length) {result.push(arr.slice(i, i + 10)); // 一次截取10个用于分堆
KKKKKKKKKKKKKK
i = i + 10; // 这10个截取完,再准备截取下10个}return result;}KKKKKKKKKKKK
const allTableData = ref([]);const tableData = ref([]);const loading = ref(false);// 第一步,请求大量数据时候,转成二维数组,分堆分组分KKKKKKKKKK块存储onMounted(async () => {loading.value = true;const res = await axios.get("http://124.223.69.156:3300/bigData");KKKKKKKKallTableData.value = averageFn(res.data.data);// 也可以存一份原始值,留作备用,都行的// const originalAllTableData = allTableData.value;loading.value = false;load();
KKKKKK
});const load = async () => {// console.log("自动多次执行之,首次执行会根据高度去计算要执行几次合适");//KKKK 第四步,触底加载相当于把二维数组的每一项取出来用,用完时return停止即可if (allTableData.value.length == 0) {console.log("没数据啦");return;}// 第二步,加载的时候,把二维数组的第一项取出来,拼接到要展示的表格数据中去let arr = allTableData.value[0];tableData.value = tableData.value.concat(arr);// console.log(tableData.value);// 第三步,拼接展示以后,再把二维数组的第一项的数据删除即可allTableData.value.shift();};</script>

本篇文章到这里就结束了,如果对你有所帮助就点个赞吧 会持续更新技术文章


http://www.ppmy.cn/news/1530086.html

相关文章

从底层原理上解释 ClickHouse 的索引

ClickHouse 是一款高性能的列式数据库&#xff0c;它通过列式存储、稀疏索引、MergeTree 引擎等技术实现了极高的查询效率和吞吐量。索引是数据库中提高查询效率的关键机制之一。为了深入了解 ClickHouse 中的索引实现机制&#xff0c;我们将从底层原理、关键数据结构以及 Clic…

基于微信小程序的智慧物业管理系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码 精品专栏&#xff1a;Java精选实战项目…

第十章,XML

高级编程 文章目录 高级编程第十章&#xff0c;XML一&#xff0c;XML简介二&#xff0c;XML编写注意事项三&#xff0c;转移符四&#xff0c;XML解析器五&#xff0c;XML命名空间六&#xff0c;解析XML技术七&#xff0c;DOM解析XML八&#xff0c;保存XML文件 第十章&#xff0…

新电脑工作流搭建记录-前端篇

vscode&#xff1a; url: Visual Studio Code - Code Editing. Redefined 插件&#xff1a;Chinese、git history、git graph、codelf、css peek、auto closed tad、auto rename tag、Quokka.js、Image preview Node 官网直接下载&#xff1a;下载 | Node.js node版本管理…

macOS设置 Redis自启动

macOS自定义开机启动程序 1、打开 自动操作app里面的应用程序 过程资料 1、https://juejin.cn/post/7123098435254747149 2、https://blog.twofei.com/889/ 2、编写脚本&#xff0c;可以点击右上角运行测试&#xff0c;保存为 app https://juejin.cn/post/7123098435254747149…

使用数据基础描述进行连续变量的特征提取

在数据科学与机器学习的过程中,数据的描述性统计和时间特征工程是十分重要的环节。描述性统计有助于快速理解数据的分布情况,而时间特征则能从时间数据中提取出有意义的信息,如趋势和周期性,帮助模型提升预测能力。本教程将围绕如何利用描述性统计量和时间数据来创建特征,…

python-简单的数据结构

题目描述 小理有一天在网上冲浪的时候发现了一道很有意思的数据结构题。 该数据结构形如长条形。 一开始该容器为空&#xff0c;有以下七种操作。 1 a从前面插入元素 a ; 2 从前面删除一个元素; 3 a从后面插入一个元素; 4 从后面删除一个元素; 5 将整个容器头尾翻转; 6 输出个…

Nexus3的妙用

nexus 3使用场景 Nexus是一个全能仓库,通过部署nexus可以实现包含yum、apt、Maven、pypi、docker等的多种仓库。以下是nexus的适用场景: 当公共仓库无法访问或缓慢时,搭建nexus。比如国内docker无法访问,需要镜像加速。可以使用海外主机部署nexus,在nexus中创建docker(p…