乐趣区

简单介绍节流与防抖

拆解 JS 的节流、防抖

节流和防抖为了优化前端性能而生,所有的概念都是基于业务衍生而来的

本质都是节省开销,使得性能交互更加友好。比如 http 请求和 DOM 操作等绑定事件以及重排重绘等大的开销,防抖是只触发一次,节流是多久触发一次。

都是指定时间只能执行一次,只不过这个指定时间的 == 计算起点 == 不一样。 记住这点就能分清节流和防抖了。

防抖:

计算起点:从最后一次触发监听事件开始计算。最后一次之前的触发,都会被舍弃掉 (clearTimeout),重新计算时间

  • 搜索框,当用户不断输入值时,防抖可以极大优化 ajax 请求,而不是每输入一个就发起一次 ajax 请求
  • 触发 window 的 resize / scroll 事件,比如滚动加载更多
function debounce(fn, delay) {
  let timer = null
  return function () {
    // 每次触发事件的时候,都将原来的定时器给清除掉,重新计算时间
    clearTimeout(timer)
    timer = setTimeout(function () {fn.apply(this, arguments)
    }, delay)
  }
}

节流:

计算起点:从上一次监听事件执行或者最开始算起。

对一些频繁的操作, 设置节流时间间隔 ,降低操作的触发频率,比如 2s 内的所有操作,在 2s 时执行一次。多余操作会被舍弃 (clearTimeout),比如:

  • 拖拽 / mousedown / keyup
function throttle(fun, delay) {
  let last, timer
  return function () {
    let me = this
    let args = arguments
    let now = +new Date()

    // 当到达了设置的间隔时间的时候,即执行
    if (last && now < last + delay) {clearTimeout(timer)
      timer = setTimeout(function () {
        last = now
        fun.apply(me, args)
      }, delay)
    } else {
      last = now // 记录开始计时的时间
      fun.apply(me, args) // 首次执行
    }
  }
}

进阶:

当然,上述只是基本的节流和防抖,还是那句话,代码怎么写,完全看业务怎么需要了。比如防抖函数要求第一次触发的时候立即执行。

退出移动版