分时与节流

分时与节流

其实是两种场景下的JS性能优化的方案。你尽可以想象成倚天剑和屠龙刀,都是非常锋利好用的东东,起码切个大白菜胡萝卜啥的是肯定没问题的~~

1. 节流函数

js中的函数,大多情况都是由用户主观上触发的。
比如点击某个按钮触发某函数啊,文本框内容改变时触发某函数啊等等,这种情况一般是不需要考虑性能问题的。
但是有些情况下,函数的触发并不受用户的直接控制。在这些场景下,函数就会被过度频繁的调用造成性能下降的问题了,比如以下情况:

window.onresize事件。

我们给window对象绑定了resize事件,当浏览器大小改变时,这个事件的触发频率特别高。

mousemove事件。

如果我们给一个div节点绑定了拖拽事件,那么div节点被拖动时,也会频繁的触发该拖拽事件的函数。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
<head lang="en">
<meta charset="UTF-8">
<title>不节流</title>
</head>
<body>

</body>
</html>
<script>
//不节流
window.onresize = function(){
console.log('hello');
};
</script>


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
//************节流函数**********************
var throttle = function(fn,interval){
var _self = fn;//保存需要被延时执行的函数引用
var timer;//定时器
var firstTime = true;//是否是第一次调用
return function(){
//将参数列表和this都先保存下来,以备延时函数调用
var args = arguments;
var _me = this;
console.log(_me);//追踪this的指向
if(firstTime){//如果是第一次调用,不需要延迟执行
_self.apply(_me,args);//调用函数
firstTime = false;//将标志位置为假
return;//执行完函数后返回,下面的代码无需执行
}
if(timer){//如果定时器还在,说明前一次延迟执行还没完成,直接返回,下面的代码无需执行
return;
}

timer = setTimeout(function(){
clearTimeout(timer);//清空timer
timer = null;
_self.apply(_me,args);//调用函数
},interval || 500);
};
};

//测试一下节流吧~~
window.onresize = throttle(function(){
console.log('hello');//这里要注意this作用域问题,这里是指向外面的window
});

2. 分时函数

有时,某些函数确实是用户主动调用的,但因为一些客观的原因,这些函数严重的影响了页面性能。
比如数据量庞大的列表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<script>

var arr = [];//900个好友的数据
for(var i=0;i<900;i++){
arr.push({name:i});
}
//渲染好友列表
var renderFriendList = function(data){
for(var i=0;i<data.length;i++){
var div = document.createElement('div');
div.innerHTML = "朋友"+data[i]['name'];
document.body.appendChild(div);
}
};

renderFriendList(arr);
</script>

那么这种情况下,我们就可以利用setInterval函数来分时创建了。

比如有900条数据,我可以一次只创建10个dom节点,分90次创建完。这样做因为有时间段间隔开了,内存和cpu就有了腾挪余地,不至于出现卡顿或死翘翘了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<script>
var arr = [];//900个好友的数据
for(var i=0;i<900;i++){
arr.push({name:i});
}
//创建一个好友节点
var createOneFriend = function(data){
var div = document.createElement('div');
div.innerHTML = "朋友"+data['name'];
document.body.appendChild(div);
};
//***************分时函数**********************
//arr是数据,fn是回调函数,count是每次创建的节点数
var timechunk = function(arr,fn,count){
var timer;
//创建dom节点函数
var start = function(){
for(var i=0;i<Math.min(count,arr.length);i++){//最后一批数据,可能arr.length小于count
var obj = arr.shift();//数组出列1个数据,长度减1
fn(obj);//调用
}
};
return function(){
timer = setInterval(function(){
if(arr.length ===0){//数组容器为空,说明都创建完毕了
clearInterval(timer);//清除定时器
return;//返回
}
start();//开始创建节点
},500);//时间间隔为500毫秒
};
};
//分批渲染,每次创建10个节点
var renderList = timechunk(arr,createOneFriend,10);
//测试一下吧~~
renderList();
</script>

文章目录
  1. 1. 分时与节流
  2. 2. 1. 节流函数
    1. 2.1. window.onresize事件。
    2. 2.2. mousemove事件。
  3. 3. 2. 分时函数
  4. 4. 那么这种情况下,我们就可以利用setInterval函数来分时创建了。
|