参考文档:http://www.zyiz.net/tech/detail-16035.html
编写动画循环时,关键是要知道循环的延迟时间多长合适,即GPU处理生成 每张图片的速度是否和浏览器屏幕刷新频率一致。
如果GPU处理生成每张图片的速度 < 屏幕刷新频率,就会出现多次刷新时显示同一张图片的现象,即用户会感觉动画出现卡顿;
如果GPU处理生成每张图片的速度 > 屏幕刷新频率,就会出现有些图片没有被展示出来,也就是我们说的丢帧现象。
大多数显示器的刷新频率是60Hz,相当于每秒钟重绘60次。
setInterval 定时器
-
是在特定的时间间隔去执行任务,时间间隔需要自己设定,为了平滑的显示动画,我们一般设置延迟时间是为1000/60;
-
但是因为setInterval是宏任务,需要等同步任务、微任务执行完成才会执行,如果同步任务、微任务的任务执行时间较长超过定时器得设定时间,那setInterval最终执行时间是大于设置时间,用户就会感觉动画出现卡顿。
var e = document.getElementById("e");
let left = 0;
let toRight = true
function render() {
if(toRight) {
if(left >= 100) {
toRight = false;
}
left++;
}else{
if(left <= 0) {
toRight = true;
}
left--;
}
e.style.left = `${left}px`;
}
setInterval(render, 1000/60);
requestAnimationFrame
-
原生的API去执行动画的效果,回调函数执行次数通常与浏览器屏幕刷新次数相匹配,一般是16ms/每次,即60ms/帧
-
执行时机: 下次重绘前执行
-
当
requestAnimationFrame()
运行在后台标签页或者隐藏的<iframe>
里时,会被暂停调用以提升性能和电池寿命。
var e = document.getElementById("e");
let left = 0;
let toRight = true
function render2() {
if(toRight) {
if(left >= 100) {
toRight = false;
}
left++;
}else{
if(left <= 0) {
toRight = true;
}
left--;
}
e.style.left = `${left}px`;
}
(function loop() {
render2();
requestAnimationFrame(loop)
})()
requestAnimationFrame与setInterval的区别?
-
setInterval动画延迟时间需要手动设置,且执行时间不稳定,无法保证按时绘制每一帧图片
-
requestAnimationFrame不需要指定帧速率,浏览器内部会自行计算每一帧的执行时间
-- 当显屏幕示器将一帧画面绘制完成后,在准备读取下一帧之前,显示器会发出一个垂直同步信号(vertical synchronization)给 GPU,GPU收到信号后开始生成新的图片
-- 即requestAnimationFrame的回调任务会在每一帧的开始时执行
网友评论