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
は、2つのループ間で経過したミリ秒数です。
@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);
_
このフィルターの「半減期」(古い値から新しい安定した値への中間移動に必要なフレーム数)は、filterStrength*Math.log(2)
(強度の約70%)です。
たとえば、_20
_の強さは、14フレームで瞬時に変化し、28フレームで3/4、46フレームで90%、99%で変化します。 92フレーム。約30 fpsで実行されているシステムの場合、パフォーマンスの急激な急激な変化は0.5秒で明らかになりますが、単一フレームの異常は「差」の5%だけシフトするため、「破棄」されます。
以下は、10fpsに瞬間的に低下し、その後最大50fpsに達する〜30fpsゲームのさまざまなフィルター強度の視覚的な比較です。ご覧のとおり、フィルター値を低くすると、「良い」変更がより迅速に反映されますが、一時的なしゃっくりの影響も受けやすくなります。
最後に、 例 上記のコードを使用して実際に「ゲーム」ループのベンチマークを行います。
requestAnimationFrame についてはどうですか?
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)
}
);
これを使用してfpsを計算します
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');
}
}
私の2セント:
最適化を比較するのに役立ちます。もちろん、テストのためだけにリソースを少し燃やします。
理想的には、アプリのフレームレートは、イベント、ループなどを使用する場合、フル使用時に、秒単位で50フレームを超えないようにする必要があります。
とにかく、少なくとも現時点では、画面が60hzを超えると更新されません。
人間は24 FPS未満のラグを感じます。これは1000/24 = 41ms
したがって、フレームの41ミリ秒は、感情がフリーズする前の最後の重要な最低ポイントです。
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
}
)
<span id="kFps"></span>
<progress id="kpFps" value="0" min="0" max="100" style="vertical-align:middle"></progress>
アイデアを得るためのループである50ミリ秒間隔がスムーズに維持されるはずです!進行状況バーのジャンプを確認しますか?これはフレーム損失であり、ブラウザは次のフレームにジャンプすることで犠牲を払おうとしますが、それを避ける必要があります!
let t
for (let i=0;i<99999;i++){
t = setTimeout(function(){
console.log("I am burning your CPU! " + i)
clearTimeout(t)
},50)
}