使用 requestAnimationFrame 在 Canvas 中计算 FPS
如何计算画布游戏应用程序的 FPS?我看过一些例子,但没有一个使用 requestAnimationFrame,我不确定如何在那里应用他们的解决方案.这是我的代码:
How could I calculate the FPS of a canvas game application? I've seen some examples, but none of them use requestAnimationFrame, and im not sure how to apply their solutions there. This is my code:
(function(window, document, undefined){
var canvas = document.getElementById("mycanvas"),
context = canvas.getContext("2d"),
width = canvas.width,
height = canvas.height,
fps = 0,
game_running = true,
show_fps = true;
function showFPS(){
context.fillStyle = "Black";
context.font = "normal 16pt Arial";
context.fillText(fps + " fps", 10, 26);
}
function gameLoop(){
//Clear screen
context.clearRect(0, 0, width, height);
if (show_fps) showFPS();
if (game_running) requestAnimationFrame(gameLoop);
}
gameLoop();
}(this, this.document))
canvas{
border: 3px solid #fd3300;
}
<canvas id="mycanvas" width="300" height="150"></canvas>
顺便问一下,我可以添加任何库来监控性能吗?
By the way, is there any library I could add to surpervise performance?
推荐答案
不要使用 new Date()
此 API 有几个缺陷,仅对获取当前日期 + 时间有用.不适用于测量时间跨度.
Do not use new Date()
This API has several flaws and is only useful for getting the current date + time. Not for measuring timespans.
Date-API 使用操作系统的内部时钟,该时钟不断更新并与 NTP 时间服务器同步.这意味着,这个时钟的速度/频率有时比实际时间快,有时慢 - 因此不能用于测量持续时间和帧速率.
The Date-API uses the operating system's internal clock, which is constantly updated and synchronized with NTP time servers. This means, that the speed / frequency of this clock is sometimes faster and sometimes slower than the actual time - and therefore not useable for measuring durations and framerates.
如果有人更改系统时间(手动或由于 DST),如果单帧突然需要一个小时,您至少可以看到问题.或者是消极时期.但如果系统时钟与世界时间同步的速度快 20%,则几乎无法检测到.
If someone changes the system time (either manually or due to DST), you could at least see the problem if a single frame suddenly needed an hour. Or a negative time. But if the system clock ticks 20% faster to synchronize with world-time, it is practically impossible to detect.
此外,Date-API 非常不精确 - 通常远小于 1 毫秒.这使得它对于帧率测量尤其无用,其中一个 60Hz 帧需要约 17 毫秒.
Also, the Date-API is very imprecise - often much less than 1ms. This makes it especially useless for framerate measurements, where one 60Hz frame needs ~17ms.
Performance API 专为此类用例而设计,可等效于 new Date()
.只需选择其他答案之一并将 new Date()
替换为 performance.now()
,就可以开始了.
The Performance API has been specificly made for such use cases and can be used equivalently to new Date()
. Just take one of the other answers and replace new Date()
with performance.now()
, and you are ready to go.
来源:
与 Date.now() 不同的是,Performance.now() 返回的值始终以恒定速率增加,与系统时钟无关(可以手动调整或通过 NTP 等软件进行调整).否则,performance.timing.navigationStart + performance.now() 将大约等于 Date.now().
Also unlike Date.now(), the values returned by Performance.now() always increase at a constant rate, independent of the system clock (which might be adjusted manually or skewed by software like NTP). Otherwise, performance.timing.navigationStart + performance.now() will be approximately equal to Date.now().
https://developer.mozilla.org/en-US/docs/Web/API/Performance/now
对于窗户:
[时间服务] 调整本地时钟频率以使其能够收敛到正确的时间.如果本地时钟与【准确时间样本】的时间差太大,无法通过调整本地时钟来校正时钟频率,时间服务将本地时钟设置为正确的时间.
[The time service] adjusts the local clock rate to allow it to converge toward the correct time. If the time difference between the local clock and the [accurate time sample] is too large to correct by adjusting the local clock rate, the time service sets the local clock to the correct time.
https://technet.microsoft.com/en-us/library/cc773013(v=ws.10).aspx
相关文章