关于防抖和节流
防抖和节流
作用
- 这两个名词是两种解决方案的称呼,为了解决频繁触发某一个函数时,限制它的调用次数,让它不要那么频繁的被调用。
为啥要这么做
- 首先呢,在浏览器中,有2个概念,一个叫重绘,一个叫**回流**。这两个现象,是在浏览器渲染页面的时候会发生的,当页面的布局不改变,仅仅是字体大小颜色等改变时就会发生重绘;当页面布局发生改变(比如width、height、margin、padding等),会发生回流。
- 上述的这两个现象挺影响性能的,所以当我们的操作会导致发生这两个现象时,一般就可以使用防抖和节流来,尽可能的减少这样的操作,不至于让我们的程序挂掉。当然不止这样情况下才能用哈,比如触发ajax请求的时候其实也可以用,根据需要来判断。
使用
防抖
- 原理:通过定时器来限制我们的操作只能在一个限制的时间后才能执行,当在这个限制时间内再次触发这一操作,重新开始计时,时间到后,在执行操作。
- 举例:根据显示器窗口的宽来实时的设置合适的高,让背景图可以以最完美的比例,完全显示。(具体实现看这里),这里对window的resize事件,进行防抖的操作
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20// 保存定时器
let timeout = null;
/**
des:防抖函数
@params:{fun:要调用的函数}
@params:{wait:设置定时器延迟执行的时间}
*/
let debounce = function (fun,wait) {
// 清除上次保存的定时器
clearTimeout(timeout);
// 创建新定时器 并保存
timeout = setTimeout(() => {
// 执行要操作的函数
fun();
}, wait);
}
// 监听窗口变化事件
window.addEventListener('resize', () => {
debounce(changeH,1000);
});
节流
- 原理:持续触发某一个函数(事件)的时候,每隔一段时间只执行一次;
- 实现:有两种方式,一种是通过时间戳一种是通过设置定时器。
- 时间戳版本:触发事件前记录一个时间,当触发事件时再记录当前时间,然后让2个时间做差在和我们设置的事件周期比较,如果大,执行事件并更新时间;小于,不执行。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24// 节流函数---时间戳版本
// 设置初始化时间
let initDate = Date.now();
/**
des:防抖函数
@params:{fun:要调用的函数}
@params:{wait:设置定时器延迟执行的时间}
*/
let throttleOne = function (fun, wait) {
// 获取当前时间
let currentDate = Date.now();
// 当执行函数的时间戳和第一次的时间戳做差大于设置的周期时,才执行函数,并更新时间戳
if (currentDate - initDate > wait) {
fun();
// 更新初始化的时间为当前时间
initDate = currentDate;
} else {
console.log('没执行');
}
}
// 监听窗口变化事件
window.addEventListener('resize', () => {
throttleByTimeStamp(changeH, 1000);
}); - 设置定时器版本:设置一个变量用来保存定时器,然后每次每次触发事件前,判断改变量是否有定时器,没有正常执行,执行后清楚触发器;如果有触发器,则不进行操作,等待上次的触发器执行完毕。
- 特点:这个形式就是,第一次操作一定会触发事件的执行。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20// 节流函数---定时器版本
// 用来保存定时器
let timer = null;
let throttleTwo = function (fun, wait) {
// 定时器存在不执行函数,不存在就执行函数
if (timer == null) {
timer = setTimeout(
() => {
fun();
timer=null;
}, wait
);
}else{
console.log('没有执行');
}
}
// 监听窗口变化事件
window.addEventListener('resize', () => {
throttleTwo(changeH, 1000);
});
总结
2者的不同
防抖是在一段时间后,一定会执行一次
节流是在一段时间内,一定会执行一次
使用场景
这两种操作要达到的目的是一样的,但是因为特点不同,所以使用场景有时候也会有一点不同;
防抖
- 比如我们这个例子,用防抖比较好,因为当窗口一直在变化,最后还是会停止,一但停止,就必须要保证容器大小一定要按背景图比例调整好,显示完美的效果给用户。
节流
- 当我们的页面在无线加载的场景下,需要用户在滑动滚动条的时候,来不断的请求ajax,所以用节流就比较好。
学习参考链接
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!