返回
手撕代码系列(三):一石二鸟探寻防抖和节流的多种实现思路
前端
2024-01-22 00:20:21
在前端开发中,我们经常会遇到这样的场景:用户在操作某个元素时,我们希望在用户停止操作后执行某个函数。比如,当用户在输入框中输入时,我们希望在用户停止输入后才进行搜索。或者当用户在页面上滚动时,我们希望在用户停止滚动后才加载更多内容。
为了实现这样的需求,我们可以使用防抖(debounce)和节流(throttle)两种技术。
防抖
防抖的核心思想是:当外界不再变化时,再去做响应。
举个例子,当用户在输入框中输入时,如果我们每次输入都向服务器发送请求,那么就会无意义地消耗服务器资源。因此,我们可以使用防抖来限制请求的发送频率,比如每隔500毫秒发送一次请求。这样,当用户输入速度很快时,服务器也不会收到太多的请求。
节流
节流的核心思想是:不管外界如何变化,始终保持着自己的响应频率。
举个例子,当用户在页面上滚动时,如果我们每次滚动都加载更多内容,那么页面就会变得非常卡顿。因此,我们可以使用节流来限制加载内容的频率,比如每隔100毫秒加载一次内容。这样,当用户滚动速度很快时,页面也不会出现卡顿的情况。
防抖和节流的实现
防抖和节流的实现有很多种方法,这里介绍两种最常用的方法:
- setTimeout()方法
我们可以使用setTimeout()
方法来实现防抖和节流。
// 防抖
function debounce(func, wait) {
let timer = null;
return function() {
let args = arguments;
if (timer) {
clearTimeout(timer);
}
timer = setTimeout(() => {
func.apply(this, args);
}, wait);
};
}
// 节流
function throttle(func, wait) {
let lastTime = 0;
return function() {
let now = Date.now();
if (now - lastTime >= wait) {
func.apply(this, arguments);
lastTime = now;
}
};
}
- requestAnimationFrame()方法
我们还可以使用requestAnimationFrame()
方法来实现防抖和节流。
// 防抖
function debounce(func, wait) {
let timer = null;
return function() {
let args = arguments;
if (timer) {
cancelAnimationFrame(timer);
}
timer = requestAnimationFrame(() => {
func.apply(this, args);
});
};
}
// 节流
function throttle(func, wait) {
let lastTime = 0;
return function() {
let now = Date.now();
if (now - lastTime >= wait) {
func.apply(this, arguments);
lastTime = now;
}
};
}
防抖和节流的使用场景
防抖和节流在前端开发中有很多应用场景,这里列举几个常见的场景:
- 搜索框 :当用户在搜索框中输入时,我们使用防抖来限制请求的发送频率,避免无意义地消耗服务器资源。
- 页面滚动 :当用户在页面上滚动时,我们使用节流来限制加载内容的频率,避免页面卡顿。
- 按钮点击 :当用户点击按钮时,我们使用节流来限制按钮的点击频率,避免按钮被多次触发。
- 窗口调整大小 :当用户调整窗口大小时,我们使用节流来限制窗口调整大小的事件触发频率,避免浏览器卡顿。
总结
防抖和节流是前端性能优化必备的两个小技巧。掌握了这两个小技巧,我们可以轻松地优化页面的性能,提高用户体验。