1. 防抖(Debounce)
防抖的核心是 延迟执行,当高频事件触发时,只有在事件停止触发后的指定时间间隔内不再有新事件,才会执行目标函数。
典型场景:搜索框输入联想、窗口resize
事件。
2. 节流(Throttle)
节流的本质是 稀释执行频率,无论事件触发多频繁,目标函数在指定时间间隔内只会执行一次。
典型场景:滚动加载更多、按钮频繁点击的提交保护。
区别总结:
特性 | 防抖 | 节流 |
---|---|---|
触发条件 | 事件停止后执行 | 固定间隔执行 |
执行次数 | 最后一次触发有效 | 每个间隔内至少执行一次 |
适用场景 | 输入联想、搜索 | 滚动事件、高频点击 |
/**
* 防抖函数
* @param {Function} fn 目标函数
* @param {number} delay 延迟时间(毫秒)
* @returns {Function} 包装后的防抖函数
*/
function debounce(fn, delay = 300) {
let timer = null;
return function(...args) {
if (timer) clearTimeout(timer); // 清除旧定时器
timer = setTimeout(() => {
fn.apply(this, args); // 确保this指向正确
timer = null;
}, delay);
};
}
Vue组件中使用防抖:
/**
* 节流函数
* @param {Function} fn 目标函数
* @param {number} interval 时间间隔(毫秒)
* @returns {Function} 包装后的节流函数
*/
function throttle(fn, interval = 1000) {
let lastTime = 0;
return function(...args) {
const now = Date.now();
if (now - lastTime >= interval) {
fn.apply(this, args); // 确保this指向正确
lastTime = now;
}
};
}
Vue组件中使用节流:
300-500ms
,避免用户输入卡顿。16ms
(接近60FPS)或100ms
(保守节流)。将防抖/节流逻辑封装为可复用的指令:
// 防抖指令 v-debounce
Vue.directive('debounce', {
inserted(el, binding) {
const [fn, event, delay] = binding.value;
const debouncedFn = debounce(fn, delay);
el.addEventListener(event, debouncedFn);
el._debouncedFn = debouncedFn; // 保存引用以便移除
},
unbind(el, binding) {
const [_, event] = binding.value;
el.removeEventListener(event, el._debouncedFn);
}
});
// 使用示例
直接使用Lodash的debounce
和throttle
:
import { debounce, throttle } from 'lodash';
export default {
methods: {
handleSearch: debounce(function() { /* ... */ }, 500),
handleScroll: throttle(function() { /* ... */ }, 100)
}
};
手动实现的防抖/节流需在组件销毁时清除定时器:
export default {
data() {
return {
timer: null
};
},
methods: {
handleResize() {
this.timer = setTimeout(() => {
// 业务逻辑
}, 300);
}
},
beforeDestroy() {
clearTimeout(this.timer); // 清除未执行的定时器
}
};
确保防抖/节流函数内this
指向Vue实例:
// 错误示例:直接调用导致this丢失
const debouncedFn = debounce(this.fetchData, 500);
button.addEventListener('click', debouncedFn); // this可能指向window
// 正确做法:使用箭头函数或bind
button.addEventListener('click', () => debouncedFn.call(this));
过长的间隔会导致用户体验下降(如按钮点击无响应),需根据场景平衡性能与体验。
场景:无限滚动加载
关键点:
isLoading
)防抖与节流是优化高频事件的核心手段,正确使用可显著提升应用性能与用户体验。在Vue中,推荐以下实践:
通过合理应用这两种技术,可以有效解决搜索联想、滚动加载、按钮防重等高频场景的性能问题。