[英]Frame rate reported by requestAnimationFrame is sometimes higher than the display's refresh rate
我正在使用以下内容来记录应用程序的帧速率:
let _lastCalledTime;
let _fps;
let _frame = 0;
let _csv = 'Frame,Timestamp,FPS';
const _refreshLoop = () =>
window.requestAnimationFrame((timestamp) => {
if (!_lastCalledTime) {
_lastCalledTime = timestamp;
_fps = 0;
} else {
const delta = (timestamp - _lastCalledTime) / 1000;
_lastCalledTime = timestamp;
_fps = 1 / delta;
}
_csv += `\n${_frame++},${timestamp},${_fps}`;
_refreshLoop();
});
_refreshLoop();
这是我在这里找到的一些代码的变体: https://www.growthwiththeweb.com/2017/12/fast-simple-js-fps-counter.html
每次渲染一帧时,使用传递给回调的timestamp
参数计算自上一帧以来经过的时间。 这用于计算 FPS 和记录为 CSV 的值。
我有一个 MacBook 和一个 Raspberry Pi 3,都以 FPS 运行,我想计算应用程序的性能。 MacBook 报告了一个非常精确的值,一旦稳定,报告的值非常接近 60 fps:
框架 | 时间戳(毫秒) | FPS |
---|---|---|
0 | 188.835 | 0 |
1 | 238.833 | 20.000800032001283 |
2 | 255.499 | 60.00240009600385 |
3 | 272.165 | 60.002400096003754 |
4 | 338.829 | 15.000600024000963 |
5 | 405.493 | 15.000600024000963 |
6 | 422.159 | 60.00240009600385 |
7 | 438.825 | 60.00240009600385 |
8 | 455.765 | 59.03187721369541 |
9 | 472.431 | 60.00240009600385 |
10 | 489.097 | 60.00240009600385 |
11 | 505.763 | 60.00240009600385 |
12 | 522.429 | 60.00240009600385 |
13 | 539.095 | 60.002400096003655 |
14 | 555.761 | 60.00240009600405 |
Raspberry Pi 对timestamp
(1 ms) 的读取精度较低,导致稳定的帧速率为 62.5/58.8 fps:
框架 | 时间戳(毫秒) | FPS |
---|---|---|
0 | 1303 | 0 |
1 | 1394 | 10.989010989010989 |
2 | 1411 | 58.8235294117647 |
3 | 1428 | 58.8235294117647 |
4 | 1444 | 62.5 |
5 | 1461 | 58.8235294117647 |
6 | 1477 | 62.5 |
7 | 1689 | 4.716981132075472 |
8 | 2321 | 1.5822784810126582 |
9 | 2443 | 8.19672131147541 |
10 | 2455 | 83.33333333333333 |
11 | 2487 | 31.25 |
12 | 2505 | 55.55555555555556 |
13 | 2521 | 62.5 |
14 | 2537 | 62.5 |
让我感到困惑的是,Raspberry Pi 有时会报告小于 16 毫秒的间隔,这表明帧速率远高于 60 fps,例如:
框架 | 时间戳(毫秒) | FPS |
---|---|---|
106 | 4378 | 40.00 |
107 | 4380 | 500.00 |
108 | 4397 | 58.82 |
109 | 4412 | 66.67 |
110 | 4428 | 62.50 |
111 | 4450 | 45.45 |
112 | 4462 | 83.33 |
113 | 4478 | 62.50 |
所以我的问题是:这怎么可能? 我最初的想法是,可能会为同一帧调用多个回调,但在这种情况下,它们会收到相同的timestamp
值( 根据规范)。 我的另外两个怀疑是,要么timestamp
非常不准确,要么requestAnimationFrame()
实际上没有锁定到显示器的刷新率,并且有时执行得更快。
requestAnimationFrame
(rAF) 不会“强制”锁定到显示刷新率编号。 一个简单的原因是很可能没有实际的“显示”,例如在无头浏览器中。 该浏览器仍然需要 rAF 以某个时间间隔触发。
您没有指定要在哪些浏览器上进行测试,但 Chrome 和 Firefox 会将 rAF 绑定到 V-Sync 信号(如果有)。 不过,我不确定他们对自适应同步监视器(如 G-Sync)做了什么。 还要注意的是,从“非动画”文档对 rAF 的第一次调用实际上计划在两个浏览器中尽快触发。
然后在 WebKit 浏览器中,他们根本不看显示器,而是使用一个简单的计时器来尝试达到 60FPS,无论实际显示速率如何。 (请注意,这仅适用于 rAF,CSS 动画同步到监视器)。
这一切都与规范一致......这给用户代理留下了一些回旋余地,即何时应该更新渲染:
如果用户代理当前能够向用户呈现浏览上下文的内容,则浏览上下文具有呈现机会,考虑到硬件刷新率限制和用户代理出于性能原因而进行的节流,但考虑到即使内容在视口之外也是可呈现的.
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.