JS中的函数节流:
在JS中的函数大多数情况下都是由用户主动触发调用的,除非是函数本身不合理,一般我们不会遇到与性能相关的问题。但是在一些少数情况下,函数的触发不是由用户直接控制的。在这些场景下,函数非常有可能被频繁的地调用,从而造成大的性能问题。
1.1函数被频繁调用的场景:
1.当我们给window对象绑定了resize事件的时候,当浏览器的窗口大小改变的时候,这个事件的触发频率就非常高了,假如我们在window.onresize事件函数中有一些跟DOM节点相关的操作,而DOM节点相关的操作往往是非常消耗性能的,就可能会造成浏览器卡顿的现象。
2.同样,如果我们给div节点绑定了一个拖拽事件(比如mousemove),当div节点被拖动的时候,也会频繁地触发该拖拽事件函数。
上述例子是在使用js开发时可能会遇到的场景,当在开发时如果出现上述的情况就会造成性能的问题,所以,为了解决上述问题,我们引入了函数节流的概念。
1.2函数节流的原理:
我们观察上述提到的例子,可以整理出一个共同点,就是函数被触发的频率太高了。比如说当我们通过拖拽来改变窗口大小的时候,打印窗口大小的工资在一秒钟内进行了十次,但是我们实际上只需要两次或者三次。这就需要我们按时间段来忽略掉一些事件请求,显然我们可以借助setTimeout来实现。
1.3函数节流的实现:
如下所示,有这样一个代码片段:
<body>
<div style="height: 500px; width: 300px; background-color: rgb(244, 199, 207);"></div>
<div style="height: 500px; width: 300px; background-color: rgb(239, 131, 16);"></div>
<div style="height: 500px; width: 300px; background-color: rgb(11, 66, 194);"></div>
<div style="height: 500px; width: 300px; background-color: rgb(177, 21, 244);"></div>
<div style="height: 500px; width: 300px; background-color: rgb(75, 180, 115);"></div>
<div style="height: 500px; width: 300px; background-color: rgb(163, 122, 150);"></div>
<div style="height: 500px; width: 300px; background-color: rgb(39, 34, 35);"></div>
<div style="height: 500px; width: 300px; background-color: rgb(209, 218, 40);"></div>
<div style="height: 500px; width: 300px; background-color: rgb(63, 179, 215);"></div>
<script >
function handler(){
console.log('页面发生了滚动');
}
document.addEventListener('scroll',handler);
</script>
</body>
当我们不添加节流函数时,只要页面一滚动,控制台就会输出
这样在开发过程中就会出现一些性能上的问题,当我们使用函数节流来优化时,一般有两种思路。
1.通过时间戳来实现:
<body>
<div style="height: 500px; width: 300px; background-color: rgb(244, 199, 207);"></div>
<div style="height: 500px; width: 300px; background-color: rgb(239, 131, 16);"></div>
<div style="height: 500px; width: 300px; background-color: rgb(11, 66, 194);"></div>
<div style="height: 500px; width: 300px; background-color: rgb(177, 21, 244);"></div>
<div style="height: 500px; width: 300px; background-color: rgb(75, 180, 115);"></div>
<div style="height: 500px; width: 300px; background-color: rgb(163, 122, 150);"></div>
<div style="height: 500px; width: 300px; background-color: rgb(39, 34, 35);"></div>
<div style="height: 500px; width: 300px; background-color: rgb(209, 218, 40);"></div>
<div style="height: 500px; width: 300px; background-color: rgb(63, 179, 215);"></div>
<script >
//传递两个参数,一个是要执行的程序,一个时设置的延迟时长
function throttle(func,delay){
//存储上一次函数执行的时间戳,初始值为0
var start=0;
return function(){
var that=this;
var args=arguments;
var current=Date.now();
//判断前后两次执行的差值是否大于等于设置的延迟时长
if(current-start>=delay){
func.call(that,args)
start=current;
}
}
}
function handler(){
console.log('页面发生了滚动');
}
document.addEventListener('scroll',throttle(handler,1000));
</script>
</body>
如上所示,就是通过时间戳来实现函数节流的方式,通过上述的代码,可以实现延迟1000ms再去执行函数。
2.使用定时器来实现:
<body>
<div style="height: 500px; width: 300px; background-color: rgb(244, 199, 207);"></div>
<div style="height: 500px; width: 300px; background-color: rgb(239, 131, 16);"></div>
<div style="height: 500px; width: 300px; background-color: rgb(11, 66, 194);"></div>
<div style="height: 500px; width: 300px; background-color: rgb(177, 21, 244);"></div>
<div style="height: 500px; width: 300px; background-color: rgb(75, 180, 115);"></div>
<div style="height: 500px; width: 300px; background-color: rgb(163, 122, 150);"></div>
<div style="height: 500px; width: 300px; background-color: rgb(39, 34, 35);"></div>
<div style="height: 500px; width: 300px; background-color: rgb(209, 218, 40);"></div>
<div style="height: 500px; width: 300px; background-color: rgb(63, 179, 215);"></div>
<script >
//定时器写法
function throttle(func,delay){
var timer=null;
return function(){
var that=this;
var args=arguments
if(!timer){
timer=setTimeout(function(){
func.call(that,args)
timer=null;
},delay)
}
}
}
function handler(){
console.log('页面发生了滚动');
}
document.addEventListener('scroll',throttle(handler,1000));
</script>
</body>