前端优化代码性能:防抖和节流

229 阅读2分钟

防抖和节流都是性能优化手段

什么是防抖? 防抖:单位时间内,频繁触发事件,只执行最后一次。 防抖的主要应用场景:

  • 搜索框搜索输入。只需用户最后一次输入完,再发送请求
  • 手机号、邮箱验证输入检测等

什么是节流? 节流:单位时间内,频繁触发事件,只执行一次。 节流的主要应用场景:

  • 高频事件 例如 resize 事件、scroll 事件等
  • 手机号、邮箱验证输入检测等

如下代码举一个简单的例子:

 <div class="box"></div>
  <script>
    const boxDom = document.querySelector('.box')
    let count = 1
    function mousemove() {
      count++
      boxDom.innerHTML = count
    }
    boxDom.addEventListener('mousemove', mousemove)

如上边代码显示给div盒子添加了mousemove鼠标移动时间。如果不防抖或者节流的代码。鼠标一滑动,这个事件会瞬间触发很多次,盒子上的数字会快速跳动(进行自加)。
如下图是节流优化的代码

    // 节流
    // 一定要有返回值,且返回值为一个函数,第二个值为延时的时间
    function throttle(fn, delay) {
      let timer
      return function () {
        if (timer) {
          return
        }
        timer = setTimeout(() => {
          fn.apply(this, arguments);
          // timer = 0
          timer = null
        }, delay)
      }
    }
    // 节流处理后无论怎样移动鼠标,内部调用的函数最快也只能固定的延时后再次执行
    // 这里throttle第一个参数是移动时间调用的函数,
    boxDom.addEventListener('mousemove', throttle(mousemove, 1000))

如下图是防抖优化后的代码

    // 这里throttle第一个参数是移动时间调用的函数,
    boxDom.addEventListener('mousemove', throttle(mousemove, 1000))
    // 防抖
    function throttle(fn, delay) {
      let timer
      return function () {
        if (timer) {
          clearTimeout(timer)
        }
        timer = setTimeout(() => {
          fn.apply(this, arguments);
          // timer = 0
          timer = null
        }, delay)
      }
    }
    // 防抖处理后,快速移动鼠标,内部函数不会被执行,只有停止移动并且延时过后才会执行一次

它们的相同点:

  • 都可以通过使用 setTimeout 来实现
  • 降低回调执行频率。节省计算资源

不同点:

  • 函数防抖,在一段连续操作结束后,处理回调,利用 clearTimeout 和 setTimeout 来实现。函数节流,在一段连续操作中,每一段时间只执行一次,频率较高的事件中使用来提高性能
  • 函数防抖关注一定时间连续触发的事件,只在最后执行一次,而函数节流一段时间内只执行一次