后端一次给你10万条数据,如何优雅展示?


前言

如果后端真的返回给前端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("消耗的时间");
  });

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

总结

原文地址

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值