为什么requestiAnimationFrame如此断断续续且前后不一致? ubuntu上的chrome

问题描述 投票:1回答:1

这可能是在黑暗中拍摄,但我不知道是什么原因造成的。

我已经使用webgl开发了一个游戏引擎。我的主要测试浏览器是firefox,一切正常。即使我正在做更激烈的事情(例如与多个帧缓冲区混合),也不会出现延迟或随机停顿。

但是,在Chrome浏览器中则完全是另外一回事。 Chrome甚至在执行最简单的任务时都难以保持稳定的fps。我决定创建一个实验,看看问题出在我的代码中还是在requestAnimation循环中。这是我运行的代码:

<!DOCTYPE html>
<html>
<body>
<div id="fpsCounter"></div>

Lowest fps
<div id="minFps"></div>

<br>
Highest fps
<div id="maxFps"></div>
<script>
    var minFps = 999;
    var maxFps = 0

    var fps = 0;
    var last = performance.now();
    var now;
    var fpsUpdateTime = 20;
    var fpsUpdate = 0;
    var fpsCounter = document.getElementById("fpsCounter");
    var minFpsEle = document.getElementById("minFps");
    var maxFpsEle = document.getElementById("maxFps");
    function timestamp(){
        return window.performance && window.performance.now ? window.performance.now() : new Date().getTime();
    }


    var getMaxFps = false;
    setTimeout(function(){
        getMaxFps = true;
    }, 2000);

    function gameLoop(){
        now = performance.now();
        if(fpsUpdate == 0){
            fps = 1000 / (now - last);
            fpsUpdate = fpsUpdateTime;
        }
        fpsUpdate--;

        fpsCounter.innerHTML = fps;
        if(parseInt(fps, 10) < parseInt(minFps, 10)){
            minFps = parseInt(fps, 10);
            minFpsEle.innerHTML = minFps;
        }

        if(parseInt(fps, 10) > parseInt(maxFps, 10) && getMaxFps){
            maxFps = parseInt(fps, 10);
            maxFpsEle.innerHTML = maxFps;
        }

        last = now;
        requestAnimationFrame(gameLoop);
    }
    gameLoop();
</script>
</body>

</html>

所有代码所做的就是循环播放动画帧并将fps放入div。在Firefox上,它的工作原理和整个游戏引擎一样,平均保持在58左右,并且永远不会低于52 fps。 Chrome很难达到40 fps以上,并且经常会跌破28 fps。奇怪的是,Chrome经常出现一些速度突增,Chrome最高fps是99 fps,但这一点也没有意义,因为稳定的60 fps更重要。

详细信息:

Firefox version: 55.0.2 64-bit
Chrome version: 60.0.3112.78 (official version) 64-bit
OS: Ubuntu 16.04 LTS
Ram: 8gb
GPU: gtx 960m
Cpu: intel core i7HQ

这是Chrome的性能外观:enter image description here

javascript google-chrome firefox requestanimationframe
1个回答
0
投票

我制作了这个用于测试的简约html页面:

<!DOCTYPE html>
<html>
<head>
    <title>requestAnimationFrame</title>
</head>
<body>
    <canvas id="canvas" width="300" height="300"></canvas>
    <script>
    "use strict"

    // (tested in Ubuntu 18.04 and Chrome 79.0)
    //
    // requestAnimationFrame is not precise
    // often SKIPs a frame
    // hardware acceleration makes it worse

    function loop() {
        requestAnimationFrame(loop)
        var ctx = document.getElementById("canvas").getContext("2d")
        ctx.fillStyle = "red"
        ctx.fillRect(100,100,200,100)
    }

    loop()
    </script>
</body>
</html>

summary - dev tools image

没有内存泄漏问题。脚本执行时间可以忽略不计。

fps - dev tools image

FPS的行为不一致(在Ubuntu上运行Chrome)。

此测试中,问题是硬件加速。

FPS为禁用硬件加速时确定

我的游戏架构

function gameLoop() {
    drawGameCanvas()
    // this makes game logic *synced* to animation frame
    // without being included in its execution;
    // eventual frame skipping is acceptable
    setTimeout(updateGameLogic, 1)
}
    
function drawGameCanvas() { 
    // some code here
} 

function updateGameLogic() {
    // some code here
    requestAnimationFrame(gameLoop)
}

gameLoop()
© www.soinside.com 2019 - 2024. All rights reserved.