JS 中的防抖与节流详解(含 React 实践)

在前端开发中,防抖(debounce)和节流(throttle)是常用的性能优化手段,尤其适用于高频事件(如输入、滚动、窗口缩放等)。

一、什么是防抖(Debounce)?

防抖是指在事件被触发 n 秒后再执行回调,如果 n 秒内事件又被触发,则重新计时。常用于输入框实时搜索、窗口 resize 等场景。

典型应用场景

  • 搜索框输入自动联想
  • 窗口大小调整
  • 表单验证

手动实现防抖函数

1
2
3
4
5
6
7
8
9
function debounce(fn, delay = 300) {
let timer = null;
return function (...args) {
clearTimeout(timer);
timer = setTimeout(() => {
fn.apply(this, args);
}, delay);
};
}

React 中使用防抖

1
2
3
4
5
6
7
8
9
10
11
12
13
import { useRef } from "react";
function useDebounce(fn, delay = 300) {
const timer = useRef();
return (...args) => {
clearTimeout(timer.current);
timer.current = setTimeout(() => {
fn(...args);
}, delay);
};
}
// 用法
const handleChange = useDebounce((e) => setValue(e.target.value), 500);
<input onChange={handleChange} />;

二、什么是节流(Throttle)?

节流是指规定在一个单位时间内,只能触发一次回调。如果这个单位时间内多次触发事件,只有一次生效。常用于页面滚动、按钮防连点等场景。

典型应用场景

  • 页面滚动监听
  • 按钮防止重复点击
  • 拖拽、resize 事件

手动实现节流函数

1
2
3
4
5
6
7
8
9
10
function throttle(fn, delay = 300) {
let last = 0;
return function (...args) {
const now = Date.now();
if (now - last > delay) {
last = now;
fn.apply(this, args);
}
};
}

React 中使用节流

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import { useRef } from "react";
function useThrottle(fn, delay = 300) {
const last = useRef(0);
return (...args) => {
const now = Date.now();
if (now - last.current > delay) {
last.current = now;
fn(...args);
}
};
}
// 用法
const handleScroll = useThrottle(() => {
// 处理滚动
}, 200);
window.addEventListener("scroll", handleScroll);

三、防抖与节流的区别

特性 防抖(debounce) 节流(throttle)
执行时机 最后一次触发后 每隔一段时间执行
典型场景 输入、搜索 滚动、拖拽、点击
原理 定时器 时间戳/定时器

四、常用第三方库

  • lodash.debounce
  • lodash.throttle

五、总结

  • 防抖适合处理高频但只需最后一次响应的场景
  • 节流适合处理高频但需定期响应的场景
  • React 中可用自定义 Hook 实现

以上内容仅供参考,请结合实际情况具体分析