JS-54 防抖(debounce)

防抖严格算起来应该属于性能优化的知识,但是实际上遇到的频率相当高,处理不当或者放任不管就容易引起浏览器卡死。

从滚动条监听的例子说起

function showTop(){

  var scrollTop=document.documentElement.scrollTop;

  console.log('滚动条位置:'+scrollTop);

}

window.onscroll=showTop

  在运行的时候会发现存在一个问题:这个函数的默认执行频率,太!高!了!。高到什么程度呢?以chrome为例,我们可以点击选中一个页面的滚动条,然后点击一次键盘的【向下方向键】,会发现函数执行了8-9次!

  然而实际上我们并不需要如此高频的反馈,毕竟浏览器的性能是有限的,不应该浪费在这里,所以接着讨论如何优化这种场景。

  基于上述场景,首先提出第一种思路:在第一次触发事件时,不立即执行函数,而是给出来一个期限值比如200ms,然后

  ①如果在200ms内没有再次触发滚动事件,那么就执行函数

  ②如果在200ms内再次触发滚动事件,那么当前的计时取消,重新开始计时

效果:既然前面都提到了计时,那实现的关键就在于setTimeout

这个函数,由于还需要一个变量来保存计时,考虑维护全局纯净,可以借助闭包来实现

  function debounce(fn,delay){

    let timer = null //借助闭包

    return function(){

      if(timer){

        clearTimeout(timer)

    }

    timer=seTieout(fn,delay)//简化写法

    }

  }

//饭后就是旧代码

function showTop(){

  let time =null //借助闭包

  return function(){

    if(timer){

      clearTimeout(timer)

    }

    timer=setTimeout(fn,delay)//简化写法

  }

}

//然后是旧代码

function showTop(){

  var scrollTop=document.scrollTop;

  console.log('滚动条位置:'+scrollTop);

}

window.onscroll=debounce(showTop,300)

到这里,已经把防抖实现了

 

防抖定义:对于短时间内连续触发的事件(上面的滚动事件),防抖的含义就是让某个时间期限(如上面的1000毫秒)内,事件处理函数只执行一次

 

 

posted @ 2025-02-06 20:48  张筱菓  阅读(20)  评论(0)    收藏  举报