前端处理后端传的10w条数据

  • 1. 这道题在考什么?
  • 2.先用 node.js 整个10w条数据
  • 3. 基础代码环境
  • 4. 常规处理方案
  • 5. 优化的第一种方式 —— 前端分页
  • 6. 再次优化
  • 7. 极致优化(最佳方案)
  • 8. 知识点补充

1. 这道题在考什么?

  • 对于性能优化的处理方案
  • 对于前端渲染机制的了解
  • 极端情况下的处理及知识领域的广度

2.先用 node.js 整个10w条数据

const http = require('http')
const PORT = 8000const server = http.createServer((req, res) => {res.writeHead(200, {//设置允许跨域的域名,也可设置*允许所有域名'Access-Control-Allow-Origin': '*',//跨域允许的请求方法,也可设置*允许所有方法"Access-Control-Allow-Methods": "DELETE,PUT,POST,GET,OPTIONS",//允许的header类型'Access-Control-Allow-Headers': 'Content-Type'})let list = [];let num = 0;for (let i = 0; i < 200; i++) {num++;list.push({src: '图片地址',text: `这是第${num}张图片`,id: num})}res.end(JSON.stringify(list))
})server.listen(PORT, () => {console.log('服务跑起来了!')
})

3. 基础代码环境

  • index.html 代码如下
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>img{width: 150px;}.flex{display: flex;padding: 10px;}</style>
</head>
<body><div id="container"></div><script src="./index.js"></script>
</body>
</html>
  • index.js 代码如下
const getList = () => {return new Promise((resolve, reject) => {// 创建请求let ajax = new XMLHttpRequest();// 这里请求的是本地服务器ajax.open('get', 'http://127.0.0.1:8000');ajax.send();ajax.onreadystatechange = function(){if(ajax.readyState == 4 && ajax.status == 200){resolve(JSON.parse(ajax.responseText))}}})
}
const container = document.getElementById("container")

4. 常规处理方案

const renderList = async () => {console.time('列表时间')const list = await getList();list.forEach( item => {const div = document.createElement('div')div.className = 'flex'div.innerHTML = `<img src="${item.src}" /><span>${item.text}</span>`container.appendChild(div)});console.timeEnd('列表时间')
}
renderList()
  • 这种方案就是简单粗暴的循环渲染
  • 此方案耗时大概是 13s
  • 这种做法当然是不可取的,等到天都黑了,用户可能会骂娘

5. 优化的第一种方式 —— 前端分页

const renderList = async () => {console.time('列表时间')const list = await getList();const total = list.length;const page = 0;const limit = 200;// 总页数const totalPage = Math.ceil(total / limit);   // Math.ceil 1.1 => 2const render = (page) => {if(page >= totalPage) returnsetTimeout(() => {for(let i = page * limit; i < page * limit + limit; i++){const item = list[i];const div = document.createElement('div')div.className = 'flex'div.innerHTML = `<img src="${item.src}" /><span>${item.text}</span>`container.appendChild(div)}render(page + 1)}, 0)}render(page);console.timeEnd('列表时间')
}
renderList()
  • 思路是把十万条数据分成 10w / 200页,再加上setTimeout,每次渲染一页,速度得到了大幅度提升
  • 方案耗时:不到 1s 搞定

6. 再次优化

const renderList = async () => {console.time('列表时间')const list = await getList();const total = list.length;const page = 0;const limit = 200;// 总页数const totalPage = Math.ceil(total / limit);   // Math.ceil 1.1 => 2const render = (page) => {if(page >= totalPage) returnrequestAnimationFrame(() => {for(let i = page * limit; i < page * limit + limit; i++){const item = list[i];const div = document.createElement('div')div.className = 'flex'div.innerHTML = `<img src="${item.src}" /><span>${item.text}</span>`container.appendChild(div)}render(page + 1)})}render(page);console.timeEnd('列表时间')
}renderList()
  • 使用 requestAnimationFrame 代替 setTimeout,减少了重排的次数,极大提高了性能

7. 极致优化(最佳方案)

const renderList = async () => {console.time('列表时间')const list = await getList();const total = list.length;const page = 0;const limit = 200;// 总页数const totalPage = Math.ceil(total / limit);   // Math.ceil 1.1 => 2const render = (page) => {if(page >= totalPage) returnrequestAnimationFrame(() => {const fragment = document.createDocumentFragment()// 文档碎片 => dom节点 不是在dom树上一部分// N次追加 => 1次for(let i = page * limit; i < page * limit + limit; i++){const item = list[i];const div = document.createElement('div')div.className = 'flex'div.innerHTML = `<img src="${item.src}" /><span>${item.text}</span>`fragment.appendChild(div)// container.appendChild(div)}container.appendChild(fragment)render(page + 1)})}render(page);console.timeEnd('列表时间')
}renderList()
  • 这里的优化点主要是:之前是创建一个div就追加一次:
div.innerHTML = `<img src="${item.src}" /><span>${item.text}</span>`
container.appendChild(div)
  • 现在改成一次性追加,极大的提高了性能。
container.appendChild(fragment)

8. 知识点补充

  • window.requestAnimationFrame()
  1. 告诉浏览器——你希望执行一个动画,并且要求浏览器在下次重绘之前调用指定的回调函数更新动画。
  2. 该方法需要传入一个回调函数作为参数,该回调函数会在浏览器下一次重绘之前执行;
  3. 若你想在浏览器下次重绘之前继续更新下一帧动画,那么回调函数自身必须再次调用window.requestAnimationFrame()
  • DocumentFragments —— 文档碎片
  1. DocumentFragments 是DOM节点。它们不是主DOM树的一部分。通常的用例是创建文档片段,将元素附加到文档片段,然后将文档片段附加到DOM树。
  2. 在DOM树中,文档片段被其所有的子元素所代替。因为文档片段存在于内存中,并不在DOM树中。
  3. 所以将子元素插入到文档片段时不会引起【页面回流】(对元素位置和几何上的计算)。
  4. 因此,使用文档片段通常会带来更好的性能。

1. 希望本文能对大家有所帮助,如有错误,敬请指出

2. 原创不易,还请各位客官动动发财的小手支持一波(关注、评论、点赞、收藏)
3. 拜谢各位!后续将继续奉献优质好文
4. 如果存在疑问,可以私信我(主页有Q)

后端一次性传了10w条数据,前端该如何处理?—— 面试高频相关推荐

  1. 前端如何处理后端一次性传来的10w条数据

    因为之前在看到了这样的文章,博主介绍了很多种实现方式,作为一名菜鸟级选手,我选择了其中一种实践了一下,因为在平时的项目中其实只需要熟练掌握一种就可以了(( • ̀ω•́ )✧还有就是我是菜鸟~) 懒加 ...

  2. 8 种方案机智应对后端一次性返回 10万 条数据

    大厂技术 高级前端 Node进阶点击上方 程序员成长指北,关注公众号 回复1,加入高级Node交流群 问题描述 面试官:后端一次性返回10万条数据给你,你如何处理? 我:歪嘴一笑,what the f ...

  3. 后端一次性返回10万条数据,使用vue,你该如何渲染?

    vue 解决同时加载万条级数据,页面渲染卡顿问题 1. 问题描述 2. 常见的解决方案 3. 解决方案流程图 4. 代码 1. 问题描述 由于业务需求,需要在一个页面中点击查询按钮时加载出所有的数据, ...

  4. 前端渲染10w条数据

    参考:https://mp.weixin.qq.com/s/a9Cso_nXjLeacilF1rs4zA 前言 如果后端真的返回给前端10万条数据,咱们前端要怎么优雅地展示出来呢?(哈哈假设后端真的能 ...

  5. 前端 传表格多条数据 给后台接收 (HTML前端表格多条数据JSON封装后;异步提交到后台处理)

    前端 传表格多条数据 给后台接收 (HTML前端表格多条数据JSON封装后:异步提交到后台处理) 1.多条数据采用checkBox 携带 //封装数据的对象var PayObj = { O_NBR:& ...

  6. JavaScript如何一次性展示几万条数据

    有一位同事跟大家说他在网上看到一道面试题:"如果后台传给前端几万条数据,前端怎么渲染到页面上?",如何回答? 于是办公室沸腾了, 同事们讨论开了, 你一言我一语说出自己的方案. 有 ...

  7. 公司新来个同事,MyBatis批量插入10w条数据仅用2秒,拍案叫绝!

    批量插入功能是我们日常工作中比较常见的业务功能之一,今天咱们来一个 MyBatis 批量插入的汇总篇,同时对 3 种实现方法做一个性能测试,以及相应的原理分析. 先来简单说一下 3 种批量插入功能分别 ...

  8. Mysql 批量插入大量数据的两种方案以及优缺点(分别是 5W 条数据和 10W 条数据)

    Mysql 批量插入(5W 条数据和 10W 条数据) 1.批量插入思路 一般是有两种不同的思路: 1.for 循环批量插入 2.生成一条 SQL 语句,比如 insert into user(id, ...

  9. java插入多条数据_如何使用java代码一次性往数据插入10W条数据

    1. 场景 : 往数据库插入10W条记录 2. 思考方案 : 单纯的我们这里不涉及其他任何操作,我们只是想生成一个10W条记录而已,中间无其他步骤,得到的效果如下图所示, 而我们又不会mysql脚本啊 ...

最新文章

  1. python 只循环目录_Python面试题目,掌握他们令你更上一层楼!附答案
  2. 当我们输入一条SQL查询语句时,发生了什么?
  3. python中Json、os、sys、hashlib等内置模块
  4. highcharts 怎么去掉鼠标悬停效果_练瑜伽减肥没效果什么原因?
  5. Intellij IDLE 中javafx使用与配置
  6. 修改注册表来修改IE的设置---资料汇总
  7. ccd后视摄像头_预计2021年全球车载摄像头总出货将达到1.43亿颗
  8. 5G和北斗,交通行业新基建的正确打开方式
  9. curl: (67) Access denied: 530的可能原因
  10. Unity3d在PC上竖屏运行
  11. Web全栈工程师年薪40w+,凭什么?
  12. linux 内核配置简介
  13. 用vscode开发autojs,输出窗口不显示任何输出结果
  14. 圣商,牢记使命成就当代圣商
  15. 高德地图根绝经纬度画线跑步软件
  16. 恶意软件NOKKI和朝鲜“Group123”APT组织关联的最新证据
  17. ncae的c语言编程高阶怎么考,NCAE考试科目.doc
  18. 单片机的中断系统(单片机)
  19. 深度学习是怎么回事?有什么用?
  20. Android 基于4G模块 GPS定位

热门文章

  1. Java手机游戏开发简明教程 (SunJava开发者认证程序员 郎锐)
  2. 跳格子/贪心算法例题详解:LeetCode605.种花问题
  3. L2-025 分而治之
  4. 边缘计算网关的定制方案
  5. SICP读书笔记 2.1
  6. 【BZOJ2754】[SCOI2012]喵星球上的点名
  7. 与机器人恋爱?人工智能已开始影响人类伦理观
  8. Module named ‘XXX’ already exists 错误解决
  9. 热乎的过万字GameFramework讲解笔记文档
  10. matlab平摆线曲率参数方程,参数方程中曲线欣赏—平摆线解读.ppt