前言
在开发过程中我们会遇到很多浏览器高频触发的事件,如按钮点击、输入框输入、页面滚动、鼠标移动等。这时候就需要用到防抖节流来优化性能,减少接口的请求次数,避免资源浪费。
防抖
防抖 (Debouncing) 功能是指触发高频事件后,n秒内函数只会执行一次。如果n秒内高频事件再次被触发,则重新计算时间。多次触发同一个事件,只执行最后一次操作。
function debounce(func, wait) {
let timeout;
return function() {
const context = this;
const args = arguments;
clearTimeout(timeout);
timeout = setTimeout(() => func.apply(context, args), wait);
};
}
// 使用示例
const myEfficientFn = debounce(function() {
console.log('Debounced function called!');
}, 250);
window.addEventListener('resize', myEfficientFn);
节流
节流 (Throttling) 功能是指高频事件触发,但在n秒内只会执行一次,所以节流会稀释函数的执行频率。多次触发同一个事件,只执行第一次操作。
function throttle(func, limit) {
let inThrottle;
return function() {
const context = this;
const args = arguments;
if (!inThrottle) {
func.apply(context, args);
inThrottle = true;
setTimeout(() => inThrottle = false, limit);
}
};
}
// 使用示例
const myEfficientFn = throttle(function() {
console.log('Throttled function called!');
}, 250);
window.addEventListener('scroll', myEfficientFn);
使用场景
节流的应用场景:
- 搜索框实时搜索:在搜索框中输入关键词时,防抖可以避免频繁地触发搜索请求,只有在用户停止输入一段时间后才发送请求,减轻服务器压力。
- 窗口大小调整:当用户调整浏览器窗口大小时,窗口大小变化事件会连续触发,使用防抖可以确保只在用户完成调整后再进行布局计算,提高性能。
- 短信验证
节流的应用场景
- 页面滚动加载:在需要实现无限滚动加载的页面中,节流可以限制滚动事件的触发频率,控制数据的加载速度,提升用户体验。
- 按钮防重复点击:当用户点击按钮进行某个操作时,使用节流可以确保按钮点击事件在一定时间内只能触发一次,防止多次点击造成误操作。
尝试用loading替代节流
以点击查询按钮为例,我们的目的是在点击按钮之后等待接口返回之后再可以下一次点击事件的触发,也就是说其实我们有可能通过禁用按钮来达到这样的效果,在触发点击事件之后先将按钮禁用等待接口返回之后再解除按钮的禁用状态,从而达到物理防抖。
如果使用了类似element-ui这种组件库,组件库中的loading组件就可以很好的帮我们替代防抖节流,因为loading的底层也是使用了定时器来控制遮罩层的消失,遮罩层的交互也很直观的告诉用户不用多次点击,因此在有组件库的项目中,我个人认为使用loading比防抖方便不少,但是也有同学认为这个不如防抖保险,可能会出现连续两次点击的情况出现,但是我没有复现出来,可能是我的手速不够快哈哈哈哈,大家有什么不同的见解也可以多多在评论区交流。