前端性能篇--------函数节流和去抖动

版权声明:转载请加入本文的出处以及地址,否侧追究版权! https://blog.csdn.net/alnorthword/article/details/88131607

写在前面的话

我们前端在开发过程经常用到 scroll 、resize等高频的事件,特别在监测浏览器变化以及在下拉加载大数据的过程中,当这些高频的事件发生时,这些高频的事件触发的频次非常高,也非常大的多,间隔的时间也很短。如果这些高频的事件中要及到大量的位置计算、DOM 操作、UI重绘等等业务,但是偏偏业务计算和操作无法在下一个 高频的事件触发之前前完成,往往会造成严重的结果,这个节结果叫浏览器掉帧。持续触发高频的事件往往会导致掉帧扩大、浏览器 CPU 使用率飙升、用户体验受到影响、浏览器崩溃。如果这个高频的时间在涉及到后端接口的交互中,而前端依赖于这个高频事件如resize,scroll等,来触发和发送相应的Http请求,在这个整个实现的过程中,我们如果不做防抖处理,那么在这个高频的事件触发的一瞬间,就会有发出无数个请求给后端,而后端在处理这些请求增加了很多没有必要的压力,更有甚者造成服务器宕机。

概念

什么是函数节流

比如我举个生活中常见的列子,有个人去拿一个空桶取打水,但是这个比较珍惜时间,不想把时间浪费在打水的过程中,于是他就把水桶放在水龙头下面,但是要把水龙头全部打开 ,打满水需要5分钟,可是中途办事情需要10分钟,可是如果全开,再去办事情,回来之后,会有很多水浪费掉,于是,就把水龙头打开一半,然后去办事情,正好回来,水桶刚好满,也减少浪费,也充分利用时间和资源。而从全部打开到打开一半,这个就是节流,节流用大白话说就是让它流动的慢些。

什么是函数去抖

最早接触这个词应该是在高中物理里面学到的,有时候开关在在真正闭合之前可能会发生一些抖动现象,如果抖动的明显的话,对应的小灯泡可能会闪烁,把灯泡闪坏了不重要,万一把眼睛再给闪坏了可就麻烦了,这个时候就有去抖电路的出现。而在我们的页面里会有这样的一个业务,页面中有一个输入框,我们根据输入框里输入内容同时可能会去掉用http接口去查询对应的数据,如果这个用户输入的同时,频繁的触发input事件,然后频繁的向后台发送请求,那么直到用户输入完成时,之前的请求都应该是多余的,假设网络慢一点,后台返回的数据比较慢,那么显示的数据可能会出现频繁的变换,直到最后的一个请求返回。

节流和去抖区别

防抖动是将多次执行变为最后一次执行,节流是将多次执行变成每隔一段时间执行。

适用场景

  1. window对象的resize事件
  2. window对象的scroll事件
  3. 拖拽时的mousemove事件
  4. 鼠标的滚动,按下,弹出等事件
  5. 文字输入、自动完成的keyup事件
  6. …等等

引用节流和不引用对比

不使用节流
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <title>Page Title</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
</head>
<body>
  <div style="margin:100px;height:200px;width:200px;background:red;"></div>
  <script>
    var i = 0
      window.addEventListener('resize', function() {
        console.log(i)
        i ++ 
      })
  </script>
</body>
</html>

移动一下触发的控制台打印情况
在这里插入图片描述

使用节流

节流的写法

    function throttle (fn, delay = 14, mustRunDelay = 14) {
      let timer = null
      let timestamp

      return function () {
        let context = this
        let args = arguments
        let now = +new Date()
        clearTimeout(timer) // 清除定时器
        if (!timestamp) {
          timestamp = now
        }
        if (now - timestamp >= mustRunDelay) {
          fn.apply(context, args)
          timestamp = now
        } else {
          timer = setTimeout(function () {
            fn.apply(context, args)
          }, delay)
        }
      }
    }

demo

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <title>Page Title</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
</head>
<body>
  <div style="margin:100px;height:200px;width:200px;background:red;"></div>
  <script>
    function throttle (fn, delay = 14, mustRunDelay = 14) {
      let timer = null
      let timestamp

      return function () {
        let context = this
        let args = arguments
        let now = +new Date()
        clearTimeout(timer) // 清除定时器
        if (!timestamp) {
          timestamp = now
        }
        if (now - timestamp >= mustRunDelay) {
          fn.apply(context, args)
          timestamp = now
        } else {
          timer = setTimeout(function () {
            fn.apply(context, args)
          }, delay)
        }
      }
    }
    var i = 0
      window.addEventListener('resize', throttle(function() {
        console.log(i)
        i ++ 
      }, 30, 30))
  </script>
</body>
</html>

移动好几下触发的控制台打印情况
在这里插入图片描述

总结是不是效果很明显。结果显而易见,在大数据情况下或者其他业务无疑是最好的实现。赶紧把这个功能收藏,或者加入你的项目中吧。

引用函数去抖动和不引用对比

不使用函数去抖动
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <title>Page Title</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
</head>
<body style="height: 5000px;">
  <div style="margin:100px;height:200px;width:200px;background:red;"></div>
  <script>
    var i = 0
    function handleAppend() {
      console.log(i);
      i ++ 
    }
    window.addEventListener('scroll', handleAppend)
  </script>
</body>
</html>

控制台打印情况
在这里插入图片描述

使用函数去抖动

函数去抖动的写法

    function debounce(fn, wait) {
      var timeout = null;
      return function() {
        if(timeout !== null)
          clearTimeout(timeout);
        timeout = setTimeout(fn, wait);
      }
    }

demo

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <title>Page Title</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
</head>
<body style="height: 5000px;">
  <div style="margin:100px;height:200px;width:200px;background:red;"></div>
  <script>
    function debounce(fn, wait) {
      var timeout = null;
      return function() {
        if(timeout !== null)
          clearTimeout(timeout);
        timeout = setTimeout(fn, wait);
      }
    }

    var i = 0
    function handleAppend() {
      console.log(i);
      i ++ 
    }
    window.addEventListener('scroll', debounce(handleAppend, 1000))
  </script>
</body>
</html>

控制台打印情况
在这里插入图片描述

总结是不是效果很明显。结果显而易见,在大数据情况下或者其他业务无疑是最好的实现。赶紧把这个功能收藏,或者加入你的项目中吧。(异步处理非常明显)

欢迎进入个人公众号 ,一起学习啊!

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/alnorthword/article/details/88131607
今日推荐