现在实现倒计时都这么卷了吗?
但是在校准时间的过程中,为了快速追赶落后的时间,时间跳动太快了,导致体验不太好,体感上感觉这时间不准呀,因此我再在那基础上再优化了一版
为求实现一版超准确!超平稳!性能极好!体验极佳的倒计时
旧版的功能实现代码
const totalDuration = 10 * 1000;
let requestRef = null;
let startTime;
let prevEndTime;
let prevTime;
let currentCount = totalDuration;
let endTime;
let timeDifferance = 0; // 每1s倒计时偏差值,单位ms
let interval = 1000;
let nextTime = interval;
setInterval(() => {
let n = 0;
while (n++ < 1000000000);
}, 0);
const animate = (timestamp) => {
if (prevTime !== undefined) {
const deltaTime = timestamp - prevTime;
if (deltaTime >= nextTime) {
prevTime = timestamp;
prevEndTime = endTime;
endTime = new Date().getTime();
currentCount = currentCount - 1000;
console.log("currentCount: ", currentCount / 1000);
timeDifferance = endTime - startTime - (totalDuration - currentCount);
console.log(timeDifferance);
nextTime = interval - timeDifferance;
// 慢太多了,就立刻执行下一个循环
if (nextTime < 0) {
nextTime = 0;
}
console.log(`执行下一次渲染的时间是:${nextTime}ms`);
if (currentCount <= 0) {
currentCount = 0;
cancelAnimationFrame(requestRef);
console.log(`累计偏差值: ${endTime - startTime - totalDuration}ms`);
return;
}
}
} else {
startTime = new Date().getTime();
prevTime = timestamp;
endTime = new Date().getTime();
}
requestRef = requestAnimationFrame(animate);
};
requestRef = requestAnimationFrame(animate);
然后有个细小的问题在于这段代码
// 慢太多了,就立刻执行下一个循环
if (nextTime < 0) {
nextTime = 0;
}
问题在于,假如遇到线程阻塞的情况,出现了倒计时落后情况严重,假设3s
,我这里设置下一个循环是0s
,然后现在倒计时当前15s
,就会看到快速倒计时到12s
,产品同学说你这倒计时还怎么加速了呀
这倒计时加速像极了职业生涯结束在加速倒计时一样,瑟瑟发抖的我立刻赶紧修复一下
其实很简单,就是把这个临近值0
设置接近每次循环的时间数即可,那么其实是看不出来每次是有在稍微加速/减速的,这里每次循环的时间数是1s
,那么我们可以将上面这段代码修改下,把以前立刻就追赶描述的操作,放缓一下追赶的脚步,以此优化用户体验
例如以前追赶2s
在3s~4s
内立刻追赶上,那么波动是很明显的,但是如果把2s
的落后秒数,平躺到接下来要倒计时的1min
里,每次大概追赶30ms
,那是看不出来滴
// 慢到一定临界点,比正常循环的时间数稍微慢点,再执行下一个循环
if (nextTime < 900) {
nextTime = 900;
}
这里我设置落后太多时,每秒追赶100ms
,假如落后2s
,20s
后就能追赶回来啦,而且看不出明显波动,时间又是被校验准确的,得到了产品同学的好评!
虽然修改很小,但是也是反复思考得到的~如果对时间要求比较严格,而且倒计时时间范围比较小,来不及把差距平摊到这么大的时间段,可建议让后端同学定时推送最新的倒计时给前端来校验时间准确性,这就万无一失啦
结语
以上是我使用requestAnimationFrame实现倒计时功能反复雕琢的心得,希望能对大家有帮助~如果能获得一个小小的赞作为鼓励会十分感激!!
作者:一只凤梨
链接:https://juejin.cn/post/7026735190634414087