JS性能优化之节流函数函数

563 阅读2分钟

「这是我参与11月更文挑战的第14天,活动详情查看:2021最后一次更文挑战

前言

函数的防抖节流,目前我们前端很多项目都运行在浏览器下,那就有很多的人机交互的操作,那我们对按钮可以有很高频率的事件点击,那这样对浏览器有一定的性能消耗的

什么是节流函数

节流节流就是节省水流、开源节流的意思,就像水龙头在流水,我们可以手动让水流(在一定时间内)小一点,但是他会一直在流。

就是我们节流的主要目的

其实函数节流,简单地讲,就是让一个函数无法在很短的时间间隔内连续调用,只有当上一次函数执行后过了你规定的时间间隔,才能进行下一次该函数的调用。

常见的场景为:

  • DOM 元素的拖拽功能实现(mousemove)
  • 搜索联想(keyup)
  • 计算鼠标移动的距离(mousemove)
  • Canvas 模拟画板功能(mousemove)
  • 射击游戏的 mousedown/keydown 事件(单位时间只能发射一颗子弹)

节流函数的核心思想

函数节流的原理挺简单的,估计大家都想到了,那就是定时器。

当我触发一个事件时,在单位时间内, 只会触发一次这个事件,如果事件触发后,又重复触发了同一事件,则忽略后面触发的事件,直到第一次事件的计时结束

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

  • 节流函数:就是n秒内只执行一次函数,如果期间多次触发,还是忽略后面的事件,直到第一次事件的计时结束
  • 奋斗函数:就是触发函数后n秒内,如果期间多次触发,会关闭之前的事件,直到最后一次事件的计时结束

实现

/**
 * @param {function} func - 执行函数
 * @param {number} delay - 延迟时间
 * @return {function}
 */
function throttle(func, delay){
  let timer = null
  return function(...arg){
    // 如果计时器不存在就不再执行后面的事情
    if(!timer){
      timer = setTimeout(()=>{
        func.apply(this, arg)
        // 为什么要置为空呢?
        // 我们重理一下节流函数的概念
        // 就是n秒内只执行一次函数,如果期间多次触发,还是忽略后面的事件,直到第一次事件的计时结束
        timer = null
      }, delay)
    }
  }
}

使用

let scrollHandler = throttle(function(e){
  console.log(e)
}, 500)
window.onscroll = scrollHandler