大家好,我是前端西瓜哥。今天说说如何计算浏览器页面的帧数。
我们需要用到 requestAnimationFrame 方法。
requestAnimationFrame 方法接受一个回调函数,并会在 浏览器下一次重渲染前调用 这个回调函数。
此外,我们通常 raf 来代表冗长的 requestAnimationFrame。
const id = window.requestAnimationFrame((timestamp) => {
// ...
})
回调函数会拿到一个高精度的时间点,称为 DOMHighResTimeStamp,表示执行回调函数的时刻。单位是 ms,有小数位,精度较高。Performance.now()
的返回值也是 DOMHighResTimeStamp。
需要注意的是这个时间点并不是当前时间的时间戳,而是从应用启动后进过的时间。
另外,可以通过 cancelAnimationFrame 方法取消,需要提供 raf 返回的 id:
cancelAnimationFrame(id);
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。
我是前端西瓜哥,欢迎关注我,学习更多前端知识。