这可能是在黑暗中拍摄的,但我不知道造成这种情况的原因。
我开发了一个带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.奇怪的是,Chrome有一些频繁的速度爆发,最高fps chrome得到了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
答案 0 :(得分: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
//
function loop() {
requestAnimationFrame(loop)
var ctx = document.getElementById("canvas").getContext("2d")
ctx.fillStyle = "red"
ctx.fillRect(100,100,200,100)
}
loop()
</script>
</body>
</html>
没有内存泄漏问题。 脚本执行时间可以忽略不计。
FPS的行为不一致(在Ubuntu上运行Chrome)。
在此测试中,问题出在硬件加速上。
禁用硬件加速后,FPS正常。
。
我对仅包含一个画布的页面进行了更多测试。 我的结论是,浏览器过于复杂(或错误),几乎不可能100%地流畅运行。
var previousTimeStamp = 0
function mainLoop(timeStamp) {
if (! shallSkipLoop(timeStamp)) { gameLoop() }
requestAnimationFrame(mainLoop)
}
function gameLoop() {
// some code here
}
function shallSkipLoop(timeStamp) {
var deltaTime = timeStamp - previousTimeStamp
previousTimeStamp = timeStamp
//
// avoiding bad frame without less than 1000 / 60 ms!!!
// this happens when browser executes a frame too late
// and tries to be on time for the next screen refresh;
// but then may start a long sequence of unsynced frames:
// one very short (like 5ms) the other very long (like 120ms)
// maybe it is a bug in browser
//
return deltaTime < 16
}
requestAnimationFrame(mainLoop)