论防抖节流

防抖和节流JavaScript 中常用的两种性能优化方式。面试中我们也会经常碰到。它们的作用是减少函数的执行次数,以提高代码的性能。

什么是防抖

防抖(Debounce)是指在事件被触发 delay 时间后再执行回调 function 函数,如果在这设置的 delay 时间内事件又被触发,则重新计时。这可以使用在些点击请求的事件上,避免因为用户的多次点击向后端发送多次请求。

防抖应用场景

  • 搜索框实时搜索:当用户在搜索框中输入内容时,通常需要实时进行搜索。使用防抖函数可以延迟搜索请求的发送,只在用户停止输入一段时间后才真正发送请求,避免频繁的请求操作。

  • 表单输入验证:在表单输入过程中,每次用户输入都可能触发验证操作。使用防抖函数可以延迟触发验证操作,只在用户输入完毕一段时间后进行验证,避免频繁的验证操作。

  • 浏览器窗口调整事件:当用户调整浏览器窗口大小时,会触发resize事件。使用防抖函数可以延迟resize事件的触发,只在用户停止调整窗口一段时间后才执行对应的操作,避免频繁的计算和布局操作。

  • 鼠标移动事件:在一些特定的交互场景中,需要根据鼠标的移动位置做出相应的交互。使用防抖函数可以延迟鼠标移动事件的触发,只在用户停止移鼠标一段时间后才执行相应的操作,避免过度频繁的操作。

作者:anyup
链接:https://juejin.cn/post/7270532002733228068
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

什么是节流

节流(Throttle)是指规定一个单位时间(延迟 delay 时间),在这个单位时间内,只能有一次触发事件的回调函数执行,如果在同一个单位时间内某事件被触发多次,只有一次能生效。节流可以使用在 scroll 函数的事件监听上,通过事件节流来降低事件调用的频率。

节流应用场景

  • 页面滚动事件:当用户滚动页面时,会频繁触发滚动事件。使用节流函数可以控制滚动事件的触发频率,避免过多的计算和渲染操作,提高页面的性能和流畅度。

  • 窗口大小调整:当用户调整浏览器窗口大小时,会不断触发resize事件。使用节流函数可以限制resize事件的触发频率,以避免过度计算和布局操作。

  • 频繁点击按钮:在某些场景下,点击按钮可能会触发重复的提交操作。使用节流函数可以限制按钮点击的触发频率,防止重复的提交。

  • 动画场景: 避免短时间内多次触发动画引起性能问题

  • 拖拽场景: 在某些场景下,频繁触发位置变动会造成性能问题,固定时间内只执行一次,防止超高频次触发位置变动

防抖实现

实现思路

  1. 定义一个计时器变量,默认为null。
  2. 当事件触发时,清除之前的计时器。
  3. 创建一个新的计时器,延迟执行目标函数。
  4. 在在此时间内,如果再次触了事件,则重复步骤2和3。
  5. 在延迟时间内没有再次触发事件时,执行目标函数。
  6. /**
     * @desc 防抖函数:一定时间内,只有最后一次操作,再过wait毫秒后才执行函数
     * @param {Function} func 函数
     * @param {Number} wait 延迟执行毫秒数
     * @param {Boolean} immediate true 表示立即执行,false 表示非立即执行
     */
    let timeout
    
    function debounce(func, wait = 500, immediate = false) {
      // 清除定时器
      if (timeout) clearTimeout(timeout)
      // 立即执行,此类情况一般用不到
      if (immediate) {
        let callNow = !timeout
        timeout = setTimeout(() => {
          timeout = null
        }, wait)
        if (callNow) typeof func === 'function' && func()
      } else {
        // 设置定时器,当最后一次操作后,timeout不会再被清除,所以在延时wait毫秒后执行func回调方法
        timeout = setTimeout(() => {
          typeof func === 'function' && func()
        }, wait)
      }
    }
    
    

    节流实现

    实现思路

  7. 定义一个标记变量来表示是否允许执行目标函数,默认为0。

  8. 当事件触发时,检查当前的时间戳与标记变量的差值,如果差值大于设定的延迟时间,则执行函数并将标记变量设为当前的时间戳。如果差值小于设定的延迟时间,则不执行。
  9. 在指定时间间隔内再次触发事件时,则重复2步骤。
/**
 * @desc 节流函数:在一定时间内,只能触发一次
 * @param {Function} func 函数
 * @param {Number} wait 延迟执行毫秒数
 */
let previous = 0
function throttle(func, wait = 500) {
  let now = Date.now()
  if (now - previous > wait) {
    typeof func === 'function' && func()
    previous = now
  }
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值