在浏览器dom事件里面,一些事件会随着用户的操作不间断的触发,比如:为一个元素绑定拖拽事件,为页面绑定resize事件(重新调整浏览器窗口大小),页面滚动。如果dom操作比较复杂,还不间断的触发事件。这将会造成性能上的损失,导致浏览器卡顿,用户体验下降。
所以针对此类事件则需要进行节流,或者防抖动处理。
一、节流-throttle
在指定时间内,让函数只触发一次。
规定一个单位时间,在这个单位时间内,只能有一次触发事件的回调函数执行,如果在同一个单位时间,触发了多次的回调函数,那也只有一次能生效,其余的作废。
举例:
假设,我们观察的总时间为10秒钟,规定1秒作为一次事件的最小间隔时间。
如果触发事件的频率是 0.5s/次
因为控制了最多一秒一次,频率为0.5s/次,所以每一秒钟就有一次事件作废。最终控制成1s/次
实现:
第一种:采用loadsh库的_.throttle()函数
第二种:滑动为例,,我们滚动页面时,为使用节流函数之前,频繁触发了多次的函数调用,函数调用中涉及到了dom操作或者接口请求的话,那将会
进行无数次的函数调用。
采用之后,时间间隔内(这里设置300ms)多次触发了函数,只执行了一次。
<!DOCTYPE html>
<html>
<head>
<title>节流</title>
<style type="text/css">
body{
height: 4000px;
}
</style>
</head>
<body>
<script type="text/javascript">
var canRun = true;
window.onscroll = function(){
console.log('canRun', canRun);
if(!canRun) return; // 判断是否已空闲,如果在执行中,则直接return
canRun = false;
setTimeout(function(){
console.log("函数节流");
canRun = true;
}, 300);
};
</script>
</body>
</html>
二、防抖-debounce
对于一定 时间段内的 连续的函数调用,只执行一次
原理:其实就是一个定时器,当我们触发一个事件时,setTimeout让这个事件延迟一会在执行。如果在这个时间段内又触发了这个事件。那么我们就先clear掉这个定时器,在重新setTimeout一个新定时器来延迟执行。
多次调用之执行一次:
同样这边的例子是
假设,我们观察的总时间为10秒钟,规定1秒作为一次事件的最小间隔时间。
如果触发事件的频率是 0.5s/次
因为始终没法等一秒钟就被再次触发了,所以最终没有一次事件是成功的。
实现:
第一种:采用loadsh库的_.debounce()函数
第二种:滑动为例,,我们滚动页面时,为使用防抖函数之前,频繁触发了多次的函数调用,函数调用中涉及到了dom操作或者接口请求的话,那将会
进行无数次的函数调用。
采用防抖之后,只有在停止滑动后,定时结束才执行函数处理逻辑。
<!DOCTYPE html>
<html>
<head>
<title>防抖</title>
<style type="text/css">
div{
height: 4000px;
}
</style>
</head>
<body>
<div></div>
<script type="text/javascript">
window.onscroll = function(){
console.log("scroll滑动");
throttle(count);
}
function count(){
console.log("函数调用");
}
function throttle(method){
clearTimeout(method.tId);
method.tId=setTimeout(function(){
method.call();
}, 300);
}
</script>
</body>
</html>
三、区别
节流:不管事件触发的多频繁,都会保证在规定的时间内一定会执行一次真正的事件处理函数。
防抖:只在最后一次触发事件后才执行一次函数
参考:
https://blog.csdn.net/crystal6918/article/details/62236730