被后端五万条数据爆破我是怎么处理的

前言

今天面试的时候面试官直接问了一句后端一次性返回10万条数据给你,你如何处理?,我脑中浮现的第一句话就是拿着物理学圣剑找后端进行 “友好的协商”,谁打赢了听谁的。不过虽然这种情况很少,不过我在实际开发中还真遇到了类似的情况,接下来我将带着大家一些处理方案。

正文

方案一 直接渲染

如果请求到10万条数据直接渲染,页面会卡死的,很显然,这种方式是不可取的。 pass!

 async getData() {this.loading = true;const res = await axios.get("/api/getData");this.arr = res.data.data;this.loading = false;
}

方案二 setTimeout分页渲染

这个方法就是,把10w按照每页数量limit分成总共Math.ceil(total / limit)页,然后利用setTimeout,每次渲染1页数据,这样的话,渲染出首页数据的时间大大缩减了。

const renderData = async () => {const Data = await getData()const total = Data.lengthconst page = 0//每页数量const limit = 200//总页数const totalPage = Math.ceil(total / limit)const render = (page) => {if (page >= totalPage) returnsetTimeout(() => {for (let i = page * limit; i < page * limit + limit; i++) {const item = Data[i]const div = document.createElement('div')div.className = 'sunshine'div.innerHTML = `<img src="${item.src}" /><span>${item.text}</span>`container.appendChild(div)}render(page + 1)}, 0)}render(page)
}

方案三 requestAnimationFrame

使用requestAnimationFrame代替setTimeout,减少了重排的次数,极大提高了性能,建议大家在渲染方面多使用requestAnimationFrame

const renderData = async () => {const Data = await getData()const total = Data.lengthconst page = 0//每页数量const limit = 200//总页数const totalPage = Math.ceil(total / limit)const render = (page) => {if (page >= totalPage) return// 使用requestAnimationFrame代替setTimeoutrequestAnimationFrame(() => {for (let i = page * limit; i < page * limit + limit; i++) {const item = Data[i]const div = document.createElement('div')div.className = 'sunshine'div.innerHTML = `<img src="${item.src}" /><span>${item.text}</span>`container.appendChild(div)}render(page + 1)})}render(page)
}

方案四 表格滚动触底加载

原理很简单,就是在列表尾部放一个空节点,然后先渲染第1页数据,向上滚动,等到空节点出现在视图中,就说明到底了,这时候再加载第二页,往后以此类推。

至于怎么判断blank出现在视图上,可以使用getBoundingClientRect方法获取top属性。也可以用 js 的IntersectionObserver API 来实现

<script setup lang="ts">
import { onMounted, ref, computed } from 'vue'const container = ref<HTMLElement>() // container节点
const blank = ref<HTMLElement>() // blank节点
const list = ref<any>([]) // 列表
const page = ref(1) // 当前页数
const limit = 200 // 一页展示
// 最大页数
const maxPage = computed(() => Math.ceil(list.value.length / limit))
// 真实展示的列表
const showList = computed(() => list.value.slice(0, page.value * limit))
const handleScroll = () => {// 当前页数与最大页数的比较if (page.value > maxPage.value) returnconst clientHeight = container.value?.clientHeightconst blankTop = blank.value?.getBoundingClientRect().topif (clientHeight === blankTop) {// 出现在视图,则当前页数加1page.value++}
}onMounted(async () => {const res = await getList()list.value = res
})
</script><template><div id="container" @scroll="handleScroll" ref="container"><div class="sunshine" v-for="(item) in showList" :key="item.tid"><img :src="item.src" /><span>{{ item.text }}</span></div><div ref="blank"></div></div>
</template>

方案五 虚拟列表

什么是虚拟列表?

所谓的虚拟列表实际上是前端障眼法的一种表现形式。

看到的好像所有的数据都渲染了,实际上只渲染可视区域的部分罢了。如果10万条数据都渲染,那得需要多少dom节点元素呢?所以我们只给用户看,他当下能看到的如果用户要下拉滚动条或者上拉滚动条再把对应的内容呈现在可视区域内。这样就实现了看着像是所有的dom元素每一条数据都有渲染的障眼法效果了

实现

<template><!-- 虚拟列表容器,类似“窗口”,窗口的高度取决于一次展示几条数据比如窗口只能看到10条数据,一条40像素,10条400像素故,窗口的高度为400像素,注意要开定位和滚动条 --><divclass="virtualListWrap"ref="virtualListWrap"@scroll="handleScroll":style="{ height: itemHeight * count + 'px' }"><!-- 占位dom元素,其高度为所有的数据的总高度 --><divclass="placeholderDom":style="{ height: allListData.length * itemHeight + 'px' }"></div><!-- 内容区,展示10条数据,注意其定位的top值是变化的 --><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>
import axios from "axios";
export default {data() {return {allListData: [], // 所有的数据,比如这个数组存放了十万条数据itemHeight: 40, // 每一条(项)的高度,比如40像素count: 10, // 一屏展示几条数据start: 0, // 开始位置的索引end: 10, // 结束位置的索引topVal: 0, // 父元素滚动条滚动,更改子元素对应top定位的值,确保联动loading: false,};},computed: {// 从所有的数据allListData中截取需要展示的数据showListDatashowListData: function () {return this.allListData.slice(this.start, this.end);},},async created() {this.loading = true;const res = await axios.get("/api/getData");this.allListData = res.data.data;this.loading = false;},methods: {// 滚动这里可以加上节流,减少触发频次handleScroll() {const scrollTop = this.$refs.virtualListWrap.scrollTop;this.start = Math.floor(scrollTop / this.itemHeight);this.end = this.start + this.count;this.topVal = this.$refs.virtualListWrap.scrollTop + "px";},},
};
</script>

 

结尾

如果你觉得此文对你有帮助的话,点个赞,鼓励一下作者。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/708614.shtml

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

相关文章

Docker数据集与自定义镜像:构建高效容器的关键要素

目录 博客前言 一.数据卷 1.数据卷介绍 2.实战 宿主机和容器共享目录 容器和容器之间共享目录 二.自定义镜像 1.自定义镜像介绍 2.实战 2.1自定义centos&#xff0c;具备vim及ifconfig作用 构建镜像 通过镜像运行一个容器进行测试 2.2自定义tomact&#xff08;文件为…

(转载)SpringCloud 微服务(三)-Seata解决分布式事务问题

ps:这个原文写的很好&#xff0c;怕后续这个地址失效&#xff0c;备份一个留着自己学习 转自&#xff1a;SpringCloud 微服务&#xff08;三&#xff09;-Seata解决分布式事务问题_seata 黑马 代码-CSDN博客 看完了黑马程序员的免费课程&#xff0c;感觉受益匪浅&#xff0c;…

【Oracle】玩转Oracle数据库(七):RMAN恢复管理器

前言 嘿&#xff0c;数据库大魔法师们&#xff01;准备好迎接新的技术大招了吗&#xff1f;今天我们要探索的是Oracle数据库中的神奇利器——RMAN恢复管理器&#xff01;&#x1f6e1;️&#x1f4be; 在这篇博文【Oracle】玩转Oracle数据库&#xff08;七&#xff09;&#xf…

Django 表单

用Django对用户提交的表单数据进行处理&#xff08;get方式&#xff09;。 search.py 文件代码&#xff1a; from django.http import HttpResponse from django.shortcuts import render # 表单 def search_form(request): return render(request, search_form.html) # …

【4.3计算机网络】网络规划与设计

目录 1.网络规划2.逻辑网络设计3.物理网络设计 1.网络规划 需求分析->通信规范分析->逻辑网络设计->物理网络设计->实施阶段 2.逻辑网络设计 3.物理网络设计 例题1&#xff1a; 解析&#xff1a;选A。 例题2&#xff1a; 解析&#xff1a;选A。 例题3. 解析&am…

自动化威胁检测和响应

网络安全变得比以往任何时候都更加复杂和疯狂。网络威胁在不断演变&#xff0c;资金充足且持续存在的不良行为者变得更加复杂且更难以检测。预算和资产捉襟见肘&#xff0c;现代网络安全团队的任务是通过持续监控威胁、实施强有力的安全措施、教育组织最佳安全实践以及迅速修复…

关于uniapp小程序的分包问题

开发uniapp小程序时&#xff0c;在打包上传代码时会出现超出2M的打包限制不能上传&#xff0c;那么我们该怎么做呢&#xff1f; 1.对于图片&#xff0c;将图片从后端服务取&#xff0c;尽量不要放在静态资源&#xff0c;图片体积会影响打包大小。 2.使用分包&#xff0c;tabb…

transformers生成式对话机器人

生成式对话机器人是一种人工智能技术,它通过学习大量自然语言数据,模拟人类进行开放、连贯和创造性的对话。这种类型的对话系统并不局限于预定义的回答集,而是能够根据上下文动态生成新的回复内容。其核心组件和技术包括: 1、神经网络架构:现代生成式对话机器人通常基于深…

Hudi配置参数优化

1&#xff09;Commits&#xff1a;表示一批记录原子性的写入到一张表中。 2&#xff09;Cleans:清除表中不再需要的旧版本文件。 3&#xff09;Delta_commit:增量提交指的是将一批记录原子地写入MergeOnRead类型表&#xff0c;其中一些/所有数据都可以写入增量日志。 4&…

【解决】Vue3中使用element-plus菜单点击两次才高亮显示问题

【解决】Vue3中使用element-plus菜单点击两次才高亮显示问题 原因&#xff1a;我这里造成高亮点击两次才生效的原因是重复渲染造成default-active的值重置了。 状况&#xff1a;点击菜单后&#xff0c;地址栏改变、页面也跳转&#xff0c;但要点击第二次后才高亮显示。或者点击…

DEEPSORT算法:深度学习驱动下的高效多目标跟踪

DEEPSORT算法核心原理梗概 DEEPSORT&#xff08;Deep Simple Online and Realtime Tracking&#xff09;是一种基于深度学习的多目标跟踪算法。其核心原理在于利用深度学习模型进行目标检测&#xff0c;并结合卡尔曼滤波器进行目标状态预测和数据关联&#xff0c;从而实现目标…

Python:内存监测工具memory_profiler

Python内存监测工具memory_profiler memory_profiler 是一个用于监测Python代码内存使用的工具。它可以帮助开发者理解他们的程序在运行时消耗内存的情况&#xff0c;确定内存泄漏的位置&#xff0c;优化代码性能。 安装 由于memory_profiler不是Python的标准库&#xff0c;…

全国产飞腾E2000Q +复旦微FPGA的轨道交通、电力解决方案

产品概述 ITX-XMF201是一款高性能边缘计算网关主板&#xff0c;采用飞腾E2000Q 4核处理器&#xff0c;国产化率达到95%国产化。 板载2电口&#xff0c;2路CAN&#xff0c;6路RS232接口&#xff0c;1路RS485接口&#xff0c;16路GPIO&#xff0c;可以满足银行、轨道交通、电力等…

VR元宇宙的概念|VR体验店加盟|虚拟现实设备销售

VR元宇宙是一个结合了虚拟现实&#xff08;Virtual Reality&#xff09;和增强现实&#xff08;Augmented Reality&#xff09;等技术的概念&#xff0c;代表着一个虚拟的多维度世界。它是一个由数字化的空间构成的虚拟环境&#xff0c;可以通过虚拟现实设备进行交互和探索。 元…

【力扣刷题练习】56. 合并区间

题目描述&#xff1a; 以数组 intervals 表示若干个区间的集合&#xff0c;其中单个区间为 intervals[i] [starti, endi] 。请你合并所有重叠的区间&#xff0c;并返回 一个不重叠的区间数组&#xff0c;该数组需恰好覆盖输入中的所有区间 。 题目解答&#xff1a; class S…

JavaScript 解决切换图片问题

代码&#xff1a; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title><style…

华为配置攻击检测功能示例

配置攻击检测功能示例 组网图形 图1 配置攻击检测功能示例组网图 业务需求组网需求数据规划配置思路配置注意事项操作步骤配置文件 业务需求 企业用户通过WLAN接入网络&#xff0c;以满足移动办公的最基本需求。且在覆盖区域内移动发生漫游时&#xff0c;不影响用户的业务使用。…

openssl_encrypt 加密解密

DES 是对称性加密里面常见一种&#xff0c;全称为 Data Encryption Standard&#xff0c;即数据加密标准&#xff0c;是一种使用密钥加密的块算法。密钥长度是64位(bit)&#xff0c;超过位数密钥被忽略。所谓对称性加密即加密和解密密钥相同&#xff0c;对称性加密一般会按照固…

Python文件操作系统操作指南

在Python编程中&#xff0c;文件系统的管理是至关重要的技能之一&#xff0c;无论是读取文本文件、处理CSV数据、编写日志&#xff0c;还是进行文件和目录的创建、移动、复制、删除等操作。本指南将全面介绍如何利用Python标准库中的os和shutil模块来有效地管理和操作文件系统。…

车灯典型方案 H5528L 降压恒流芯片12V240V360V48V60V72V90V转9V12V 高低亮 性价比高

降压恒流芯片支持高低亮工作原理&#xff1a; 通过PWM&#xff08;脉冲宽度调制&#xff09;技术来调节开关管的开关时间&#xff0c;从而实现稳定的输出电压和电流&#xff0c;保持LED灯的亮度稳定。当需要调节LED灯的亮度时&#xff0c;可以通过改变PWM信号的占空比来实现。…