防抖与节流
防抖(Debounce)和节流(Throttle)是前端开发中常用的性能优化技术,主要用于控制高频触发的事件处理函数的执行次数。
防抖的实现
防抖的核心思想是:在事件触发后,等待一段时间,如果这段时间内没有再次触发事件,则执行处理函数;如果再次触发,则重新计时。
手写防抖代码
function debounce(func, wait) {
let timeout;
return function (...args) {
const context = this;
clearTimeout(timeout);
timeout = setTimeout(() => func.apply(context, args), wait);
};
}
Lodash 库的使用
Lodash 提供了功能强大的 _.debounce 方法,其实现与手写版本类似,但支持更多功能,如立即执行选项。
import _ from 'lodash';
const debouncedFunc = _.debounce(() => {
console.log('Debounced!');
}, 300);
节流的实现
节流的核心思想是:在一定时间间隔内,只允许处理函数执行一次。
手写节流代码
function throttle(func, wait) {
let lastTime = 0;
return function (...args) {
const now = Date.now();
if (now - lastTime >= wait) {
lastTime = now;
func.apply(this, args);
}
};
}
Lodash 库的使用
Lodash 提供了 _.throttle 方法,同样支持更多选项,如尾部调用。
import _ from 'lodash';
const throttledFunc = _.throttle(() => {
console.log('Throttled!');
}, 300);
防抖与节流的对比
| 特性 | 防抖 | 节流 |
|---|---|---|
| 执行频率 | 事件停止触发后执行一次 | 固定时间间隔内执行一次 |
| 适用场景 | 输入框搜索、窗口调整 | 滚动事件、按钮频繁点击 |
经典应用场景
防抖应用场景
- 搜索框输入联想:用户停止输入后再发送请求。
- 窗口大小调整:调整结束后重新计算布局。
- 表单验证:用户停止输入后验证表单字段。
- React 中的输入框优化:在表单组件中使用防抖来减少
onChange事件触发的频率,从而优化性能。 - Vue 中的搜索功能:在
v-model绑定的输入框中使用防抖函数,避免频繁触发搜索请求。 - API 请求优化:防止用户快速点击按钮导致多次 API 调用。
节流应用场景
- 滚动加载:滚动页面时每隔一段时间加载新内容。
- 按钮防重复点击:限制按钮点击频率。
- 鼠标移动事件:限制鼠标移动事件的触发频率。
- React 中的滚动监听:在组件中监听滚动事件时使用节流,减少渲染次数。
- Vue 中的拖拽功能:在拖拽组件中使用节流函数,优化拖拽性能。
- 游戏开发中的帧率控制:限制游戏中某些操作的触发频率以保持流畅性。
- 窗口滚动事件:在页面滚动时触发的动画效果中使用节流,避免性能瓶颈。
- 实时数据更新:在数据可视化场景中,限制图表更新的频率以提升性能。
替代方案
- RxJS:使用 RxJS 的
debounceTime和throttleTime操作符处理流式事件。 - requestAnimationFrame:对于动画相关的场景,可以使用
requestAnimationFrame替代节流。 - 自定义 Hook:在 React 中,可以封装防抖和节流的自定义 Hook。
RxJS 示例
import { fromEvent } from 'rxjs';
import { debounceTime, throttleTime } from 'rxjs/operators';
const input = document.getElementById('input');
fromEvent(input, 'input')
.pipe(debounceTime(300))
.subscribe(() => console.log('Debounced!'));
fromEvent(input, 'input')
.pipe(throttleTime(300))
.subscribe(() => console.log('Throttled!'));
requestAnimationFrame 示例
function throttleWithRAF(func) {
let ticking = false;
return function (...args) {
if (!ticking) {
requestAnimationFrame(() => {
func.apply(this, args);
ticking = false;
});
ticking = true;
}
};
}
防抖和节流是前端性能优化的利器,选择合适的实现方式和工具可以大幅提升用户体验。
→🐒

777

被折叠的 条评论
为什么被折叠?



