函数防抖与节流总结

245 阅读2分钟

防抖

函数防抖是优化高频率执行 js 代码的一种手段,可以让被调用的函数在一次连续的高频操作过程中只被调用一次

函数防抖作用:减少代码执行次数, 提升网页性能

比如,在谷歌引擎上输入自己想要搜索的内容时,当输入 j 时,为了更好的用户体验,通常都会出现对应的联想内容,这些联想内容通常都是保存在服务器上的

假设每输入一个字母就会发送一次网络请求,那么输入 javascript 就会发送 10 次网络请求,这会大大损耗系统性能,事实上我们并不需要这么多的网络请求,正确做法是在合适的情况下再发送网络请求

我们可以监听用户在某个时间内是否有再次触发事件,如果没有则发送网络请求

函数防抖应用场景:oninput / onmousemove / onscroll / onresize 等事件

用 input 模拟网络请求

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>

  <body>
    <input type="text" class="search" />
    <script>
      let search = document.getElementsByClassName("search")[0];
      let count = 0; // 记录触发的网络请求次数
      function oInputChange() {
        count++;
        console.log(`发送了${count}次网络请求`);
        console.log(this);
      }

      search.oninput = oInputChange;
    </script>
  </body>
</html>

当连续输入 javas 时共发送了 5 次网络请求

自定义防抖函数

思路:

当触发一个函数时,并不会立即执行这个函数,而是通过定时器来延迟函数的执行

如果在延迟时间内,有重新触发函数,那么取消定时器

如果在延迟时间内,没有重新触发函数,那么这个函数就正常执行(执行传入的函数)

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>

  <body>
    <input type="text" class="search" />
    <script>
      let search = document.getElementsByClassName("search")[0];
      let count = 0; // 记录触发的网络请求次数

      function oInputChange() {
        count++;
        console.log(`发送了${count}次网络请求`);
        console.log(this);
      }

      search.oninput = debounce(oInputChange, 1000);

      function debounce(fn, delay) {
        let timer = null;
        return function () {
          let _self = this,
            args = arguments;
          timer && clearTimeout(timer);
          timer = setTimeout(function () {
            fn.apply(_self, args);
          }, delay);
        };
      }
    </script>
  </body>
</html>

再次输入 javas 时只发送了一次网络请求

节流

函数节流也是优化高频率执行 js 代码的一种手段,可以减少高频调用函数的执行次数

函数节流作用:减少代码执行次数, 提升网页性能

函数节流应用场景:比如,监听页面的滚动事件、鼠标移动事件、用户频繁点击按钮操作

函数节流和函数防抖区别:

  • 函数节流是减少连续的高频操作函数执行次数 (例如连续调用 10 次, 可能只执行 3-4 次)
  • 函数防抖是让连续的高频操作时函数只执行一次(例如连续调用 10 次, 但是只会执行 1 次)

自定义节流函数

function throttle(fn, delay) {
  let timer = null;
  let flag = true;
  return function () {
    if (!flag) return;
    flag = false;
    let _self = this,
      args = arguments;
    timer && clearTimeout(timer);
    timer = setTimeout(function () {
      flag = true;
      fn.apply(_self, args);
    }, delay);
  };
}