javascript 中的防抖和节流操作

防抖和节流的使用场景

在javascript 中经常会用到一些监听事件,比如 scrollView 、mousemove 等事件。在使用这些事件的回调函数时,如果回调逻辑复杂一些,就会导致页面卡顿。 那么使用防抖和节流就能有效提升页面流畅度。除了上述的事件,也可用于多次点击事件等。

防抖和节流的介绍

防抖和节流一般需要使用setTimeout 方法

防抖(debounce)
防抖是指在多次调用时,只在最后一次调用回调时生效。需要使用setTimeout定义一个超时时间。如果在超出时间内又触发了防抖事件,那么就会使定时器重新计时。

  var timeout = null // 定义定时器对象
  // 在body 元素上监听鼠标移动事件
  document.body.onmousemove = (e) => {
  	// 判断定时器是否存在
    if (timeout) {
      // 清除上一个计时器
      clearTimeout(timeout)
    }
    timeout = setTimeout(() => {
      console.log('mouseMove') // 结束移动打印一次 mouseMove
    }, 500)
  }

上方的代码在body内监听mousemove 事件,如果不加定时器,只要你鼠标在body上移动,控制台就会打印非常多的 "mouseMove" 但是加了防抖后,变为了只在鼠标结束移动后才执行定时器内的代码。

mousemove 为鼠标移动事件 clearTimeout 方法将会清除定时器

节流(throttle)
节流是指在多次调用时,限制调用的频率,比如在mousemove 事件中,我们不需要鼠标停止移动时执行操作,而是限制每500毫秒进行一次操作:

  var timeout = false // 定义延迟状态
  // 在body 元素上监听鼠标移动事件
  document.body.onmousemove = (e) => {
  // 如果还没到延迟时间就 rertun
    if (timeout) {
      return false
    }
    // 设置延迟开始
    timeout = true
    setTimeout(() => {
      console.log('mouseMove') // 500ms打印一次 mouseMove
      // 执行代码完成 清空延迟
      timeout = false
    }, 500)
  }

稍微改动下代码,根据timeout变量判断是否可以执行代码。只有在执行完一次定时器任务后才进行下一个定时器任务,稀释了高频触发的回调。运行代码就会发现只要鼠标保持移动,那么控制台上就会一直打印,打印的频率就是定时器的执行延迟。

防抖和节流的区别

  • 防抖在一次高频事件中只在超出延迟时间后触发,大幅度减少了cpu运算的次数。
  • 节流简单来讲就是把原来很快触发的高频事件变成自定义触发时间,稀释cpu的运算次数。

总的来说防抖对性能的优化更好,但是连贯性不强。节流虽然计算次数更多,但是能给用户带来更加连贯的体验。

比如需要做一个图片跟随鼠标的功能,用防抖的话就会导致只在鼠标停止移动后图片移动,但是用节流函数就能保证一边移动鼠标一边图片跟随移动。

总结

在开发中我们还是需要更具对应的需求来选择防抖还是节流。

在一些需要持续变动的需求时可以用节流,比如跟随鼠标功能、页面变更尺寸改变dom大小等。

在一些需要防止重复操作的需求时,可以用防抖。比如 表单提交之类的按钮事件,重复点击的话我们不需要多次进行回调,那么我们显然是用防抖更好。

以上是个人对防抖节流的学习和看法,希望有帮助到各位。

有相关问题欢迎在评论区进行讨论!

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值