JavaScript “防抖”和“节流”详解与应用
在我们日常开发过程中,可能会遇到这样一些情况:当我们频繁点击页面上某个按钮或者鼠标滚轮不停地滚动的时候,会出现页面卡死的问题,用户体验就很不好,为了优化这些问题,我们引入了“防抖”和“节流”。
阅读本文,你将
- 知道什么是“防抖”,什么是“节流”;
- 了解“防抖”和“节流”各自的实现原理;
- 知道“防抖”和“节流”各自的应用场景。
1、防抖
定义:
n秒后再执行该事件,如果在这n秒内被触发了,则重新开始计时。
举个例子:我们每天上下班都会乘电梯,如果把电梯运送当做一个函数,假设电梯超时设定为20秒,不考虑容量限制。
当电梯第一个人进来之后,等待20秒,电梯自动关门运行,如果这个等待的过程中又有人进来了,20秒等待重新计时,直到20秒后关门运行,这个便是防抖。
实现原理:
每次触发事件时设置一个延迟调用方法,并且取消之前的延迟调用方法。
缺点:
如果事件在规定时间间隔内被不断地触发,则调用方法会被不断地延迟。
// 防抖函数
function debounce(fn, delay) {
let timeout = null;
return function() {
clearTimeout(timeout);
timeout = setTimeout(() => {
fn.apply(this, arguments);
}, delay);
}
}
// 处理函数
function handle() {
console.log("防抖");
}
// 比如页面滚动事件
window.addEventListener("scroll", debonce(handle, 500));
2、节流
定义:
n秒内只运行一次,若在n秒内被重复触发,只有一次生效。
举个例子:还是乘电梯,电梯门每隔20秒自动关门运行,20秒之内不管你进来几个人,只要20秒时间到了,门就自动关上。
实现原理:
每次触发事件时,如果当前有等待执行的延时函数,则直接return
// 节流函数
function throttle(fn, delay) {
let flag = true;
return function() {
if(!flag) return;
flag = false;
setTimeout(() => {
fn.apply(this, arguments);
flag = true;
}, 500)
}
}
// 处理函数
function handle() {
console.log("节流");
}
window.addEventListener("resize", throttle(handle, 500));
总结:
防抖:将多次操作合并为一次操作进行。原理是维护一个计时器,规定在delay时间后触发函数,但是在delay时间内再次触发的话,就会取消之前的计时器而重新设置,这样一来,只有最后一次操作能被触发。
应用场景:
- 搜索框搜索输入,只需要用户最后一次输入完再发送请求。
- 窗口大小resize,只需窗口调整完成后,计算窗口大小。防止重复渲染。
节流:使得一定时间内只触发一次函数。
应用场景:
- 滚动加载,加载更多或滚到底部监听。
- 搜索框,搜索联想功能。
区别:
相同点:
- 都可以通过使用setTimeout实现
- 目的都是降低回调执行频率,节省计算资源。
不同点:
节流不管事件触发有多频繁,都会保证在规定时间内一定会执行一次真正的事件处理函数,而防抖只是在最后一次事件后才触发一次函数。
转载自:https://juejin.cn/post/7072998572362301470