前言
如果后端真的返回给前端10万条数据,咱们前端要怎么优雅地展示出来呢?(哈哈假设后端真的能传10万条数据到前端)
一、使用node搭建简单的后台服务?
const express = require('express')
const app = express()
const cors = require('cors')
app.use(cors())
app.get('/api/data',(req,res)=>{
let result = []
for (let i = 0; i < 100000; i++){
result.push({
src: 'https://p3-passport.byteacctimg.com/img/useravatar/d71c38d1682c543b33f8d716b3b734ca~300x300.image',
name: `我是${i+1}号嘉宾`
})
}
res.send(result)
})
app.listen(9000,_=>{
console.log("Server is running")
})
二、前端页面
<!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>
</head>
<body>
<div id="container"></div>
<script src="./index.js"></script>
</body>
</html>
封装一个index.js文件,采用fetch请求后台的10w条数据
直接渲染
最直接的方式就是直接渲染出来,但是这样的做法肯定是不可取的,因为一次性渲染出10w个节点,是非常耗时间的,咱们可以来看一下耗时,差不多要消耗十几秒,非常消耗时间。
const container = document.getElementById("container");
fetch("http://localhost:5000/api/data", {
method: "GET",
})
.then((res) => res.json())
.then((res) => {
console.log(res);
console.time("消耗的时间");
res.forEach(el => {
const div = document.createElement('div')
div.innerHTML = `<img src="${el.src}" /><span>${el.name}</span>`
container.appendChild(div)
});
console.timeEnd("消耗的时间");
});
setTimeOut分页渲染
这个方法就是,把10w按照每页数量limit分成总共Math.ceil(total / limit)页,然后利用setTimeout,每次渲染1页数据,这样的话,渲染出首页数据的时间大大缩减了。
const container = document.getElementById("container");
fetch("http://localhost:5000/api/data", {
method: "GET",
})
.then((res) => res.json())
.then((res) => {
console.log(res);
console.time("消耗的时间");
// 使用setTimeOut实现分页
let total = res.length;
let limit = 200; // 每页200条
let page = 0;
let totalPage = Math.ceil(total / limit);
const render = (page) => {
if (page >= totalPage) return;
setTimeout(() => {
for (let i = 0; i < limit + limit * page; i++) {
const div = document.createElement("div");
div.innerHTML = `<img src="${res[i].src}" /><span>${res[i].name}</span>`;
container.appendChild(div);
}
render(page + 1);
}, 0);
};
render(page);
console.timeEnd("消耗的时间");
});