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

作者:闭包旅人时间:2026-10-24 17:08:32浏览:155

本文深入解析JavaScript中防抖(debounce)与节流(throttle)的核心原理及实现方式。通过弹簧比喻理解防抖,通过水滴比喻理解节流,并对比非立即执行、立即执行及时间戳、定时器等多种代码实现方案。文章结合resize、input等实际场景,阐述如何利用这两种技术优化高频事件处理,提升Web应用性能。

防抖(debounce)

定义:针对短时间内连续触发的事件(如滚动事件),确保在指定时间周期内,事件处理函数仅执行一次。

类比:以手指按压弹簧为例,持续按住时弹簧不会回弹,直到手指松开。

示例 resize:


function debounce(fn, wait){
    var timer = null;
    return ()=>{
        if(timer !== null){
            clearTimeout(timer);
        }
        timer = setTimeout(fn, wait);
    }
}
function handle(){
    console.log(Math.random());
}
window.addEventListener("resize",debounce(handle, 1000));

上述代码为非立即执行版本。

立即执行版本。


function debounce(fn, wait){
	let timeid, flag = true;
	return () => {
		clearTimeout(timeid);
		if(flag){
			fn();
			flag = false;
		}else{
			timeid = setTimeout(()=>{
				flag = true;
			}, wait);
		}
	}
}

拖动浏览器窗口触发 resize 事件时,handle 函数不会立即执行,而是启动定时器。若在计时期间再次触发 resize,则重新计时。此举优势在于避免频繁执行 handle 函数,仅在必要时运行,有效消除冗余操作。

常见实现方式:


const debounce = (func, delay = 200) => {
  let timeout = null
  return function () {
    clearTimeout(timeout)
    timeout = setTimeout(() => {
      func.apply(this, arguments)
    }, delay)
  }
}

节流(throttle)

定义:确保事件在指定时间段内仅执行一次。

核心意图:如同水龙头滴水,规定时间内仅执行一次,旨在降低频繁重复执行的频率。

典型应用场景:搜索框的 input 事件。

基于时间戳的计算方式:


function throttle(fn,wait){
  let startTime = 0;
  return function(){
    let endTime = Date.now();
    if(endTime-startTime>wait){
      fn();
      startTime = endTime;
    }
  }
}

基于定时器的实现方式:


function throttle(fn,wait){
  let timeid = null;
  return function(){
    if(!timeid){
       timeid = setTimeout(function(){
         fn();
         timeid = null;
       },wait)
    }
  }
}

总结

本文到此结束,希望能为读者提供帮助,并欢迎关注本站更多相关内容!

作者最新文章