zl程序教程

您现在的位置是:首页 >  IT要闻

当前栏目

如何计算浏览器页面的帧数 FPS?

2023-02-18 16:37:40 时间

大家好,我是前端西瓜哥。今天说说如何计算浏览器页面的帧数。

我们需要用到 requestAnimationFrame 方法。

requestAnimationFrame

requestAnimationFrame 方法接受一个回调函数,并会在 浏览器下一次重渲染前调用 这个回调函数。

此外,我们通常 raf 来代表冗长的 requestAnimationFrame。

const id = window.requestAnimationFrame((timestamp) => {
  // ...
})

回调函数会拿到一个高精度的时间点,称为 DOMHighResTimeStamp,表示执行回调函数的时刻。单位是 ms,有小数位,精度较高。Performance.now() 的返回值也是 DOMHighResTimeStamp。

需要注意的是这个时间点并不是当前时间的时间戳,而是从应用启动后进过的时间。

另外,可以通过 cancelAnimationFrame 方法取消,需要提供 raf 返回的 id:

cancelAnimationFrame(id);

实时显示 FPS

FPS,是 frames per second 的缩写,也就是一秒渲染了多少帧的画面。对于浏览器来说,通常 fps 为 60。

FPS = 一秒的帧数 / 1s

配合 raf 会在每次重绘前执行,我们可以计算在 1 秒内,统计调用 raf 的次数 count。当时间间隔超过 1 秒后,就读取这个 count,然后重置 count 和间隔开始时间。

实现如下:

let count = 0;
let prevTimestamp;

function showFPS(fps) {
  // 这里设置如何将 fps 数值输出
  // 比如你可以将其更新到某个 DOM 元素上
  console.log(fps);
}

function loop(timestamp) {
  if (prevTimestamp) {
    count++;
    // 间隔超过 1s,将之前计算的 count 输出
    if (timestamp - prevTimestamp >= 1000) {
      showFPS(count);
      prevTimestamp = timestamp;
      count = 0;
    }
  } else {
    prevTimestamp = timestamp;
  }
  window.requestAnimationFrame(loop);
}

window.requestAnimationFrame(loop);

理论上,我们还可以直接用 1 / timestamp * 1000 得到几毫秒内的 FPS。

但没有太大意义,因为过于微观,可能突然在某个瞬间卡顿,但很快又恢复正常,这个微小的变化容易忽略,如果体现在 1 s 中则更容易观测些。且频繁地将 FPS 值打印出来,其本身也会导致性能的下降,不利于观测。

结尾

利用 requestAnimationFrame 会在页面渲染前执行的特性,我们可以去计算页面的 FPS。

我是前端西瓜哥,欢迎关注我,学习更多前端知识。