请求动画帧

曾经面试被问到一个问题,请求10万条数据,如果让页面不卡顿。其实我当时显得就是用定时器,但是发现时间不好把控。然后查了一些资料发现 requestAnimationFrame 可以完美解决这个问题。 requestAnimationFrame 是通过请求动画帧来实现的

屏幕刷新频率

普通计算机为60HZ

动画原理

1000/60 = 计算机每16.7ms刷新一次。由于人眼的视觉停留,所以看起来是流畅的移动

setTimeout

通过设定间隔时间来不断改变图像位置,达到动画效果。但是容易出现卡顿、抖动的现象;

  • settimeout任务被放入异步队列,只有当主线程任务执行完后才会执行队列中的任务,因此实际执行时间总是比设定时间要晚;
  • settimeout的固定时间间隔不一定与屏幕刷新时间相同,会引起丢帧。

    requestAnimationFrame

    优势:由系统决定回调函数的执行时机。60Hz的刷新频率,那么每次刷新的间隔中会执行一次回调函数,不会引起丢帧,不会卡顿

案例requestAnimationFrame

requestAnimationFrame可以完美解决这个问题,而且页面不会发生卡顿。

  1. let num = 0;
  2. function raf() {
  3. num += 1;
  4. let clearInter;
  5. if (num < 100) {
  6. let span = document.createElement('span')
  7. clearInter = window.requestAnimationFrame(() => {
  8. document.querySelector('body').appendChild(span).innerHTML = `${num}res - `
  9. raf()
  10. })
  11. console.log('requestAnimationFrame');
  12. } else {
  13. console.log('gai');
  14. cancelAnimationFrame(clearInter)
  15. }
  16. }
  17. window.requestAnimationFrame(raf)

案例setInterval

使用定时器的过程,确实会发生卡顿现象,而且时间不好控制。

  1. let num1 = 0;
  2. function Interval() {
  3. let clears = setInterval(() => {
  4. num1 += 1;
  5. let span = document.createElement('span');
  6. document.querySelector('body').appendChild(span).innerHTML = `${num1}set -`
  7. if (num1 >= 100) {
  8. clearInterval(clears)
  9. }
  10. console.log('setInterval');
  11. })
  12. }
  13. Interval()