JavaScript函数节流与防抖:原理、实现与应用场景

作者:寒星时间:2026-10-23 02:00:29浏览:188

本文详解JavaScript中节流与防抖的核心概念及实现原理。通过对比scroll、resize等高频事件,阐述如何利用定时器机制控制函数执行频率,从而降低浏览器负担,提升页面性能与用户体验。

防抖和节流

防抖和节流

性能优化背景

在窗口resize、scroll滚动或输入框内容校验等操作中,若处理逻辑复杂或导致页面频繁重渲染,且事件触发频率无限制,将显著增加浏览器负担,严重影响用户体验。此时,采用debounce(防抖)和throttle(节流)策略可有效降低触发频率,同时保持功能正常。

这两种技术旨在解决项目优化问题,官方虽无严格定义,但其出现主要是为了应对短时间内连续执行事件带来的性能瓶颈和巨大的内存消耗。

此类事件通常包括scroll、keyup、mousemove和resize等,短时间内不断触发会导致极大的性能消耗,尤其是涉及DOM结构变更的操作。

节流与防抖原理相似,均旨在将规定时间内不断触发的事件更改为在特定时间间隔内触发指定次数。

节流[throttle]

节流[throttle]

通俗而言,节流如同调节水龙头:打开阀门后水流急促,为节约资源,需将水流调小,使其按一定规律在特定时间间隔内滴落。这便是节流的核心概念。

在函数实现上,通常使用setTimeout方法,计算两个时间点之差,当达到预设时间间隔时触发一次事件。以下以scroll事件为例进行说明。


/** 样式我就顺便写了 **/
<style>
 *{padding:0;margin:0;}
 .scroll-box{
  width : 100%;
  height : 500px;
  background:blue;
  overflow : auto;
 } 
 .scroll-item{
  height:1000px;
  width:100%;
 }
</style>

------------------------


/** 先给定DOM结构;**/
<div class="scroll-box">
 <div class="scroll-item"></div>
</div>

------------------------


/**主要看js,为了简单我用JQ去写了**/
<script>
 $(document).ready(function(){
  var scrollBox = $('.scroll-box');
  //调用throttle函数,传入相应的方法和规定的时间;
  var thro = throttle(throFun,300);
  //触发事件;
  scrollBox.on('scroll' , function(){
   //调用执行函数;
   thro();
  })

  // 封装函数; 
  function throttle(method,time){
   var timer = null;
   var startTime = new Date();
   return function(){
    var context = this;
    var endTime = new Date();
    var resTime = endTime - startTime;
    //判断大于等于我们给的时间采取执行函数;
    if(resTime >= time){
     method.call(context);
     //执行完函数之后重置初始时间,等于最后一次触发的时间
     startTime = endTime;
    }
   }
  }
  function throFun(){
   console.log('success');
  }
 })
</script>

通过上述函数,可实现节流效果,例如每300毫秒触发一次,具体间隔可根据需求自定义。

防抖[debounce ]

防抖[debounce ]

在编写代码前,需明确防抖概念。以电脑端两侧悬浮广告窗口为例,拖动滚动条时,广告窗口会因不断尝试居中而频繁位置变动,产生“抖动”现象。

这种频繁的位置变动称为抖动,防抖的目标正是防止此类抖动发生。

防抖的思想是:在拖动操作完成后,再重新计算两侧窗口的位置,使界面变化平滑舒适,同时大幅减少DOM结构的操作次数。

此举优化了页面性能并降低了内存消耗,对于IE等较老版本的浏览器,甚至可避免页面崩溃的风险。

书面表述为:在某个事件结束前,函数不执行;当事件结束后,经过给定的延时时间,再执行该函数,即为防抖函数。

来看代码:


//将上面的throttle函数替换为debounce函数;
function debounce(method,time){
 var timer = null ;
 return function(){
  var context = this;
  //在函数执行的时候先清除timer定时器;
  clearTimeout(timer);
  timer = setTimeout(function(){
   method.call(context);
  },time);
 }
}

思路是在函数执行前清除定时器。若函数持续执行,则不断清除定时器中的方法,直到操作结束,函数才会最终执行。

书写方式多样,核心在于思路清晰,通过大量实践即可掌握。

用途

用途

  1. 在进行keyup后台请求校验时,可使用防抖函数。若每次按键都请求一次,频率过高;使用防抖后,仅在按键结束后发起请求,大幅减少请求次数,提升性能。
  2. 在resize窗口大小调整时,可采用防抖或节流技术。
  3. 在mousemove鼠标移动事件中,既可应用防抖,也可使用节流。
  4. 对于scroll滚动条触发的事件,同样既可使用防抖,也可使用节流。
  5. 所有连续高频事件均可通过这两种方式解决,以优化页面性能。

具体选择哪种方式,主要取决于业务需求。感谢阅读,希望本文对您有所帮助,也欢迎支持本站。

作者最新文章