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

news2024/11/15 1:49:35

在这里插入图片描述

前言

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

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

虚拟列表渲染

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

<template>

<!-- 虚拟列表容器 -->

<div

class="virtualListWrap"

ref="virtualListWrap"

:style="{ height: itemHeight * count + 'px' }"

@scroll="handleScroll"

>

<!-- 占位元素,高度为所有数据的总高度 -->

<div

class="placeholderDom"

:style="{ height: allListData.length * itemHeight + 'px' }"

>

</div>

<!-- 实际显示的内容区域 -->

<div class="contentList" :style="{ top: topVal }">

<!-- 循环渲染可见的数据项 -->

<div

v-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-button

style="margin-bottom: 12px"

size="small"

type="primary"

:loading="loading"

@click="plan"

>点击请求加载</el-button

>

<el-table

height="300"

:data="arr"

border

style="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-table

v-el-table-infinite-scroll="load"

height="480"

:data="tableData"

border

style="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.coloradmin.cn/o/2150709.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

工程师 - PFM介绍

在电子电路设计中&#xff0c;PFM&#xff08;Pulse Frequency Modulation&#xff0c;脉冲频率调制&#xff09;是一种调制技术&#xff0c;其主要特点是在负载变化时调整脉冲的频率&#xff0c;而保持脉冲的宽度&#xff08;时间长度&#xff09;相对恒定。与PWM&#xff08;…

lambda 自调用递归

从前序与中序遍历序列构造二叉树 官方解析实在是记不住&#xff0c;翻别人的题解发现了一个有意思的写法 class Solution { public:TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {auto dfs [](auto&& dfs, auto&&…

深度学习-图像处理篇1.1-1.2神经网络

1.1卷积神经网络基础 卷积层 对彩色RGB图像进行卷积 1.卷积核的通道数与输入特征层的通道数相同 2.卷积输出的特征矩阵通道数与卷积核个数相同 池化层 池化中一般池化核大小和步长大小一样 思考 加上偏移量bias该如何计算? 卷积计算时加上偏移量即可 加上激活函数该如何计…

Nomad Web服务终于成熟了!

大家好&#xff0c;才是真的好。 9月份HCL Notes/Domino相关产品发布的还真不少&#xff0c;前脚刚发布了HCL Notes Domino 14.5 EA1&#xff0c;后脚就迎来了Notes Domino 14.0FP2IF1&#xff0c;还有Nomad 1.0.13版本。 在我的记忆中&#xff0c;他们不喜欢数字13&#xff…

分布式消息中间件kafka

文章目录 什么是kafka?整体架构 kafka核心概念1. 生产者 (Producer)2. 消费者 (Consumer)3. 主题 (Topic)4. 分区 (Partition)5. 经纪人 (Broker)6. 复制 (Replication)7. 消费者组 (Consumer Group)8. 日志段 (Log Segment) 主要功能1. 高吞吐量2. 可靠的消息传递3. 发布/订阅…

打印菱形(图像打印)

//打印菱形 // ---* // *** // ***** // ******* // ***** // *** // * //一共需要line行&#xff0c;分成两边&#xff0c;上半部分需要line/21行 //下半部分需要line/2行 #include<stdio.h> #define L 11 //行 #define R 11 //列 int main() {int …

十三 系统架构设计(考点篇)试题

A 对&#xff0c;B对&#xff0c;C好像是分布式中间件吧&#xff0c;D对。选C 第一题&#xff0c;感觉肯定有交互支持&#xff0c;选B;第二B。实际答案&#xff1a;D和B。 在一个分布式系统中&#xff0c;中间件通常提供两种不同类型的支持&#xff1a; &#xff08;1&#xff…

【读书笔记-《30天自制操作系统》-23】Day24

本篇内容依然比较简单&#xff0c;主要是优化窗口功能以及开发定时器应用程序。首先是优化窗口的切换功能&#xff0c;实现通过键盘和鼠标切换窗口&#xff0c;然后是实现通过鼠标关闭窗口。接着实现不同窗口输入状态的切换&#xff0c;最后是实现定时器的API与应用程序。 1.…

mybatisplus乐观锁

使用方法&#xff1a; 1.添加version锁标记字段 2.实体类添加对应字段&#xff0c;并加上Version注解 3.添加配置类 Configuration public class MpComfig {Beanpublic MybatisPlusInterceptor mpInterceptor(){MybatisPlusInterceptor mpInterceptor new MybatisPlusIntercep…

VuePress搭建文档网站/个人博客(详细配置)主题配置-侧边栏配置

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…

沟通更高效:微信群转移至企业微信操作攻略!

微信群转移到企业微信并不难&#xff0c;具体操作如下&#xff1a; 打开移动端企业微信主页&#xff0c;找到微信聊天栏中的【接收微信中的工作消息】&#xff1b; 点击【前往微信选择群聊】&#xff0c; 跳转到微信&#xff1b; 选择微信上的工作群聊&#xff0c;只能选择作…

elasticsearch同步mysql方案

文章目录 1、1. 使用数据库触发器2. 使用定时任务3. 监听MySQL二进制日志&#xff08;binlog&#xff09;4. 使用数据管道5. 使用第三方工具或服务6. 编写自定义脚本注意事项 2、1. 使用Logstash步骤&#xff1a;示例配置&#xff1a; 2. 使用Debezium步骤&#xff1a; 3. 自定…

基于python flask的高血压疾病预测分析与可视化系统的设计与实现,使用随机森林、决策树、逻辑回归、xgboost等机器学习库预测

研究背景 随着现代社会的快速发展&#xff0c;生活方式的改变和人口老龄化的加剧&#xff0c;心血管疾病&#xff0c;尤其是高血压&#xff0c;已成为全球范围内的重大公共健康问题。高血压是一种常见的慢性疾病&#xff0c;其主要特征是动脉血压持续升高。长期不控制的高血压…

wordpress更换域名后用户图片头像不显示

&#x1f3c6;本文收录于《全栈Bug调优(实战版)》专栏&#xff0c;主要记录项目实战过程中所遇到的Bug或因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&am…

进程间的通信 2 消息队列

system V IPC IPC : Inter-Process Communication (进程间通讯) System V IPC 对象共有三种&#xff1a; 消息队列共享内存信号量 System V IPC 是由内核维护的若干个对象&#xff0c;通过ipcs命名查询 每个 IPC 对象都有一个唯一的 ID&#xff0c;可以通过ftok()函数生成 …

re题(36)BUUCTF-[WUSTCTF2020]Cr0ssfun

BUUCTF在线评测 (buuoj.cn) 查一下壳&#xff0c;64位elf文件 ctrle找到main()函数 只进行了一个比较函数&#xff0c;看一下check() 猜测是a1中存放的flag&#xff0c;往下继续查看函数 把a1中存的数据都给出来了 写个脚本&#xff0c;输出一下a1&#xff0c;直接就是我们要的…

通过MCGS在ARMxy边缘计算网关上实现物流自动化

随着电子商务和智能制造的快速发展&#xff0c;物流行业面临着前所未有的挑战与机遇。高效的物流系统不仅可以加快货物周转速度&#xff0c;降低运营成本&#xff0c;还能显著提升客户满意度。 1. ARMxy BL340系列简介 ARMxy BL340系列是针对工业自动化领域设计的一款高性能、…

虚拟机的ip总是自己变化如何解决?

目录 修改配置文件&#xff1a; 如果出现错误E212&#xff1a;无法打开并写入文件&#xff1a; 如果显示当前用户没有在sudoers文件中&#xff0c;就按照下面方法操作。 修改配置文件&#xff1a; 变化的原因&#xff1a;在配置文件/etc/sysconfig/network-scripts/ifcfg-e…

Docker 里面按照ifconfig

1. 进入Docker 容器内部 docker exec -it xxx bash2. 安装 net-tools iputils-ping apt-get update && apt-get install -y net-tools apt-get update && apt-get install -y iputils-ping 3. 执行ifconfig 执行ping

如日中天的AI大模型,也到了发展幻灭期!

近期 Gartner发布了《新兴技术成熟度曲线》&#xff0c;其中生成式 AI &#xff08;GenAI&#xff09; 正式进入到了幻灭期。 2018 年 6 月&#xff0c;OpenAI发布GPT-1模型&#xff0c;生成式AI开始向产品化发展。 到2022年的GPT-3.5发布&#xff0c;并且ChatGPT首次向公众推…