前端开发中如何处理接口数据过大的问题

66 篇文章 3 订阅
16 篇文章 0 订阅

题引:

当我们在公司做项目的时候,难免会遇到后端接口直接给你返回成千上万的数据进行渲染。如果我们直接一股脑遍历添加的话,就会导致空白页面的等待时间是很长且异常卡顿,那么对于数据过大的渲染就需要进行特殊的处理。这也是一道非常经典的面试题。下面我将介绍几种通用的方法。

正文:

这里提供四种比较常见的解决方案,也是日常开发中用的较多的。

防抖节流

防抖节流这种八股文该怎么使用好像都不需要详细讲解了,直接上代码即可

该防抖函数可以实现 this指向,参数,立即执行,取消功能,返回值

function debounce(fn, delay, immediate = false,resultCall) {let timer = null;let isInvoke = false;let result = null;//返回给元素的真正函数const _debounce = function (...args) {//取消上一次的操作if (timer) clearTimeout(timer);//如果是第一次执行或者已经执行完的,采取立即执行if (immediate && !isInvoke) {result =fn.apply(this, args);if(resultCall){resultCall(result)}isInvoke = true;}//开启防抖else {timer = setTimeout(() => {//执行真正的函数result =fn.apply(this, args);if(resultCall){resultCall(result)}isInvoke = false;}, delay);}};//取消事件_debounce.cancel = function () {if (timer) clearTimeout(timer);};return _debounce;
} 

该节流函数可以实现 this指向,参数,立即执行,取消功能,返回值

function throttle(fn, interval, options = { leading: true, trailing: false }) {// 1.记录上一次的开始时间//leading记录要不要第一次触发,即要不要同步执行//trailing记录要不要进行定时器触发const { leading, trailing } = optionslet lastTime = 0let timer = null// 2.事件触发时, 真正执行的函数const _throttle = function(...args) {// 2.1.获取当前事件触发时的时间const nowTime = new Date().getTime()//要不要同步执行if (!lastTime && !leading) lastTime = nowTime// 2.2.使用当前触发的时间和之前的时间间隔以及上一次开始的时间, 计算出还剩余多长事件需要去触发函数const remainTime = interval - (nowTime - lastTime)if (remainTime <= 0) {if (timer) {clearTimeout(timer)timer = null}// 2.3.真正触发函数fn.apply(this, args)// 2.4.保留上次触发的时间lastTime = nowTimereturn}if (trailing && !timer) {timer = setTimeout(() => {timer = nulllastTime = !leading ? 0: new Date().getTime()fn.apply(this, args)}, remainTime)}}_throttle.cancel = function() {if(timer) clearTimeout(timer)timer = nulllastTime = 0}return _throttle
} 

分页处理

分页处理就不过多描述了,需要和后端进行搭配,接口传递page,size等参数

懒加载

懒加载的话这边需要判断目标标签的_offsetTop-scrollTop<clientHeight_来决定是否进行数据获取或者渲染,多用于图片懒加载(后面将会专门讲解图片懒加载的实现)。

定时处理

当我们接受到成千上万的数据要进行渲染时,可能较多的人会使用setTineout来作为定时器,通过分块的方式定时渲染。 但使用 _requestAnimationFrame_的效果是会比 setTimeout 的性能更好,因为使用前者的时候浏览器会帮我们进行处理优化,在最优的时候进行调用,而不是像后者设置一个时间。

另外,让我们往一个dom节点插入数据的时候,我们99%都会使用document.createELement,但是如果在该场景下,你插入一条数据都会造成DOM树的重新渲染,当插入的元素多时会造成没必要的开销。但是我们可以使用document.Fragment来使用,它就像vue里面的template后者react的<></>,不是一个真实的元素标签。

与_createElement_相比,它最大的好处就是不会触发DOM树的重新渲染,且不会对性能造成影响。因为所有的节点会被_一次性_插入到文档中,所以仅会发生一个重渲染的操作,而不是每个节点分别被插入到文档中从而发生多次重渲染的操作。

<!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><ul id="list"></ul><script> const total = 10000;const num = 20;const times = Math.ceil(total / num);let currentNums = 0;const ul = document.querySelector("#list");function add() {let frag = new DocumentFragment();for (let i = 0; i < num; i++) {const li = document.createElement("li");li.innerHTML = Math.floor(i + currentNums * num);frag.appendChild(li);}currentNums++;ul.appendChild(frag);if (currentNums < times) {window.requestAnimationFrame(add);}}window.requestAnimationFrame(add); </script></body>
</html> 

结尾:

以上就是对于数据过大的处理方法汇总。

最后

最近还整理一份JavaScript与ES的笔记,一共25个重要的知识点,对每个知识点都进行了讲解和分析。能帮你快速掌握JavaScript与ES的相关知识,提升工作效率。



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

人还是要有梦想的

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值