requestAnimationFrame、setTimeout、setInterval

requestAnimationFrame()

执行动画,要求浏览器在下次重绘之前调用指定的回调函数更新动画
参数:回调函数作为参数,回调函数会在下次重绘之前执行
回调函数的执行次数和浏览器的刷新频率有关
返回值: 回调列表的唯一ID标识;传入window.cancelAnimationFrame()取消回调函数
可以利用requestAnimationFrame()实现节流

let flag = false;
window.addEventListener('scroll',()=>{
	if(!flag){
		requestAnimationFrame(callback);
		flag = true;
		// 计时器可以操作实际的执行间隔
		setTimeout(() => flag = false, 50);
	}
})

setTimeout计时器: 时间到期之后,执行该段代码
setInterval定时器: 是指定何时将回调函数放入执行队列,但是没有指定什么时候执行;
requestAnimationFrame由系统回调函数的执行时间,保证回调函数在刷新间隔中执行一次,不会出现丢帧、卡顿的情况;
一般电脑的刷新频率是60HZ,也就是每秒重绘60次,大约17毫秒刷新一次;

setTimeout:

  1. 回调函数的执行时间不确定,主线程中没有任务执行的时候,才会检查执行该队列中的任务
  2. 与屏幕的刷新频率没有关系
  3. 在内存中对元素属性进行修改,然后渲染的屏幕上,如果setTimeout回调函数未执行,屏幕绘制了或者是屏幕还未绘制,但是setTimeout回调函数执行了,这两种情况就会出现掉帧、画面卡顿

设置0ms延时:

// 设置延迟0ms
setTimeout(callback,0);

注: 尽可能立即执行,但是如果嵌套调用setTimeout次数(5次以上)的话,就会设置为4ms(chrome和Firefox);未被激活的tabs,setTimeout最小延迟是1s(1000ms)

setInterval

setTnterval(callback,delay): callback中函数的执行时间,超过delay;函数之间就没有间隔执行; 也可能出现有的被跳过执行的情况

let index = 0;
let timerid = setInterval(() => {
    if(++index === 10) clearInterval(timerid);
    console.log('执行时间:',performance.now());
}, 1000);

下面是保存的执行结果:

执行时间: 1084.725000000617
执行时间: 2084.6200000014505
执行时间: 3084.69000000332
执行时间: 4084.7300000023097
执行时间: 5084.780000004685
执行时间: 6084.815000001981
执行时间: 7083.890000001702
执行时间: 8083.904999999504
执行时间: 9083.995000000868
执行时间: 10083.944999998494

执行的时间间隔是一次要比1000ms短

setTimeout实现setInterval

setTimeout(function setInterval2(){
	setTimeout(setInterval2,2000);
},2000);

每个1s打印从from-to的值:

setInterval实现
function print(from, to) {
	let current = from;
	let timerId = setInterval(function() {
		alert(current);
		if (current === to) clearInterval(timerId);
		current++;
	},1000);
}
setTimeout实现
function print(from, to) {
	let current = from;
	setTimeout(function go(){
		alert(current);
		if (current < to) {
			setTimeout(go, 1000);
		}
		current++;
	},1000);
}

requestAnimationFrame优势:

  1. CPU节能:setTimeout,当页面隐藏或最小化的时候,还是会在后台运行,此时刷新动画没用,但是requestAnimationFrame和系统保持同步,页面未激活的状态下,requestAnimationFrame会停止执行;页面激活,会从上次停止的位置开始执行;
  2. 函数节流: resizescroll拖拽事件中,避免在函数执行间隔内,函数多次执行。

参考文章:
【1】window.requestAnimationFrame
【2】window.setTimeout
【3】window.setInterval
【3】从打字机效果的 N 种实现看JS定时器机制和前端动画
【4】Scheduling: setTimeout and setInterval

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值