我如何检查我的JavaScript的fps?我正在使用它循环:
gameloopId = setInterval(gameLoop, 10);
在gameLoop
中,查看最后一个循环中new Date
和new Date
之间的区别(将其存储在变量中)。
换一种说法:
var lastLoop = new Date();
function gameLoop() {
var thisLoop = new Date();
var fps = 1000 / (thisLoop - lastLoop);
lastLoop = thisLoop;
...
}
thisLoop - lastLoop
是两个循环之间传递的毫秒数。
@Slaks的代码仅为您提供最后一帧的瞬时FPS,这可能会因打嗝而变化或误导。我更喜欢使用易于编写和计算的低通滤波器来消除快速瞬变并显示最近结果的合理伪平均值:
// The higher this value, the less the fps will reflect temporary variations
// A value of 1 will only keep the last value
var filterStrength = 20;
var frameTime = 0, lastLoop = new Date, thisLoop;
function gameLoop(){
// ...
var thisFrameTime = (thisLoop=new Date) - lastLoop;
frameTime+= (thisFrameTime - frameTime) / filterStrength;
lastLoop = thisLoop;
}
// Report the fps only every second, to only lightly affect measurements
var fpsOut = document.getElementById('fps');
setInterval(function(){
fpsOut.innerHTML = (1000/frameTime).toFixed(1) + " fps";
},1000);
这个过滤器的“半衰期” - 从旧值中间移动到新的稳定值所需的帧数是qazxsw poi(大约是强度的70%)。
例如,filterStrength*Math.log(2)
的强度将中途移动到14帧的瞬时变化,28帧中的3/4,46帧中的90%,以及92帧中的99%。对于一个运行速度大约为30fps的系统,性能的突然剧烈变化将在半秒内显而易见,但仍然会“抛弃”单帧异常,因为它们只会将值偏移5%。
下面是一个~30fps游戏的不同过滤器强度的视觉比较,其瞬间下降到10fps,然后速度高达50fps。正如您所看到的,较低的过滤器值更快地反映了“良好”的变化,但也更容易受到临时打嗝的影响:
最后,这里是20
使用上面的代码来实际测试“游戏”循环。
我用它来计算fps
an example
怎么样 var GameCanvas = document.getElementById("gameCanvas");
var GameContext = doContext(GameCanvas,"GameCanvas");
var FPS = 0;
var TimeNow;
var TimeTaken;
var ASecond = 1000;
var FPSLimit = 25;
var StartTime = Date.now();
var TimeBefore = StartTime;
var FrameTime = ASecond/FPSLimit;
var State = { Title:0, Started:1, Paused:2, Over:3 };
var GameState = State.Title;
function gameLoop() {
requestAnimationFrame(gameLoop);
TimeNow = Date.now();
TimeTaken = TimeNow - TimeBefore;
if (TimeTaken >= FrameTime) {
FPS++
if((TimeNow - StartTime) >= ASecond){
StartTime += ASecond;
doFPS();
FPS = 0;
}
switch(GameState){
case State.Title :
break;
case State.Started :
break;
case State.Paused :
break;
case State.Over :
break;
}
TimeBefore = TimeNow - (TimeTaken % FrameTime);
}
}
Sprites.onload = function(){
requestAnimationFrame(gameLoop);
}
function drawText(Context,_Color, _X, _Y, _Text, _Size){
Context.font = "italic "+ _Size +" bold";
Context.fillStyle = _Color;
Context.fillText(_Text, _X, _Y);
}
function doFPS()(
drawText(GameContext,"black",10,24,"FPS : " + FPS,"24px");
}
function doContext(Canvas,Name){
if (Canvas.getContext) {
var Context = Canvas.getContext('2d');
return Context;
}else{
alert( Name + ' not supported your Browser needs updating');
}
}
?
requestAnimationFrame
我的2美分:
对我来说比较优化很有用。当然,只需要进行测试就可以获得一些资源。
理想情况下,在使用事件,循环等时,您的应用帧速率应保持在50帧以上,完全使用时。
无论如何,屏幕不会刷新超过60hz,至少现在。
人类在24 FPS下感觉滞后,这是1000/24 = 41ms
因此,在冻结感觉之前,一帧的41ms是最后一个关键的最低点。
var before,now,fps;
before=Date.now();
fps=0;
requestAnimationFrame(
function loop(){
now=Date.now();
fps=Math.round(1000/(now-before));
before=now;
requestAnimationFrame(loop);
console.log("fps",fps)
}
);
let be = Date.now(),fps=0;
requestAnimationFrame(
function loop(){
let now = Date.now()
fps = Math.round(1000 / (now - be))
be = now
requestAnimationFrame(loop)
if (fps < 35){
kFps.style.color = "red"
kFps.textContent = fps
} if (fps >= 35 && fps <= 41) {
kFps.style.color = "deepskyblue"
kFps.textContent = fps + " FPS"
} else {
kFps.style.color = "black"
kFps.textContent = fps + " FPS"
}
kpFps.value = fps
}
)
只需一个循环来获得想法,50ms间隔,应该保持平稳!看到进度条跳跃?这是帧丢失,浏览器试图通过牺牲来保持,通过跳到下一帧,我们必须避免这种情况!
<span id="kFps"></span>
<progress id="kpFps" value="0" min="0" max="100" style="vertical-align:middle"></progress>