防抖与节流

文章介绍了前端开发中用于性能优化的防抖和节流技术,它们用于限制函数的触发频率,减少不必要的计算和网络请求。防抖技术在事件频繁触发时,保证在一段时间间隔后只执行一次,例如王者荣耀的技能冷却;而节流则确保在一定时间内只处理一次事件,比如输入监听或滚动事件。文章提供了代码示例和应用场景,并提醒注意在使用时保持this的正确指向。
摘要由CSDN通过智能技术生成

防抖与节流

前端页面中存在许多被频繁触发的函数,如果不限制其触发的频率,会对性能造成很大的影响,如果这些函数还涉及网络通讯,则还会对后端造成巨大的压力。

而防抖与节流是常见的两种性能优化技术,用以限制函数被触发的频率。

1.节流

什么是节流?

在前端页面中,点击一个按钮会触发一些事件。但是这些用这些事件有可能会被频繁的触发,比如说用户可能会疯狂的点击,而这样会给带来一些不合理的情况。

比如有些网站评论区,用户如果在短时间内点击了多次发布按钮,可能会出现同样的评论会重复发了好几次的情况。这显然是不合理的也十分影响性能。

而使用防抖,可以避免一个事件短时间内重复被触发。在函数调用后的一段时间内(比如0.5秒),再次点击触发,也不会生效。

有一个非常贴切的例子:王者荣耀的英雄技能CD。比如一个英雄放大招以后,那么在未来一段时间内他都不能再放大招。这期间他无论怎么点击,就算把玻璃都点碎了,也没有用。

代码

function debounce(fn, wait) {
    let timer = null;
    return function (...args) {
        if (!timer) {
            fn();
            timer = setTimeout(() => {
                timer = null;
            }, wait);
        }
    };
}

使用场景

向后端交互的事件(如请求验证码、发送评论)等

2.防抖

什么是防抖?

高频率触发的事件,在指定的单位时间后才执行。如果在此期间,有重复触发了这个时间,就会重新计时。

类似于游戏中的回城机制,必须要等待几秒后才可以真的回城,如果再次期间有任何微操,回城就会被打断。

代码

function debounce(fn, wait) {
  let timer = null;
  return function (...args) {
    //如果已经有定时器了,则取消这个定时器(里面的代码也就不会执行了)
    clearTimeout(timer);
     //这里会立即返回一个定时器id,在wait时间后,该定时器会自动执行里面的代码
    timer = setTimeout(() => {
      timer = null;
      fn(...args);
    }, wait);
  };
}

使用场景

  1. input 输入事件,滚动事件或resize事件等
  2. 以及其他的只关心最终状态的情形

3.Demo及注意事项

其实两者没有太大区别,只要能满足自己的需求就好。
在使用过程中,记得关注this的指向。

<!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>防抖与节流</title>
  </head>
  <body>
    <div>
      不用节流
      <button onclick="log()">不用防抖触发点击事件</button><br /><br />
      节流
      <button onclick="log_debounce()">使用防抖触发点击事件</button><br /><br />
    </div>
    <div>
      不使用防抖
      <label>的输入监听</label><input type="text" id="text1" /><br /><br />
    </div>
    <div>
      防抖
      <label>的输入监听</label><input type="text" id="text2" />
    </div>
    <script>
      //节流
      function throttle(fn, wait = 500) {
        let timer = null;
        return function (...args) {
          if (!timer) {
            fn();
            timer = setTimeout(() => {
              timer = null;
            }, wait);
          }
        };
      }
      let x = 1;
      let log = () => {
        console.log(x++);
      };
      let log_debounce = throttle(() => {
        console.log(x++);
      }, 1000);

      //防抖
      function debounce(fn, wait = 500) {
        let timer = null;
        return function (...args) {
          //如果已经有定时器了,则取消这个定时器(里面的代码也就不会执行了)
          clearTimeout(timer);
          //这里会立即返回一个定时器id,在wait时间后,该定时器会自动执行里面的代码
          timer = setTimeout(() => {
            timer = null;
            fn(...args);
          }, wait);
        };
      }
      let text1 = document.querySelector("#text1");
      let text2 = document.querySelector("#text2");
      let watch = function () {
        // console.log(this);
        console.log(this.value);
      };
      // 这里记得使用bind改变this指向
      let watch_throttle = debounce(watch.bind(text2), 1000);
      text1.oninput = watch;
      text2.oninput = watch_throttle;
    </script>
  </body>
</html>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值