问题 html5 帧率


我正在考虑使用javascript制作游戏逻辑游戏,并使用HTML5画布元素为游戏设置动画。我的目标是编写适用于浏览器和更新智能手机的东西。所以我编写了一个快速程序,在屏幕上移动100个圆圈并向我显示帧速率。我对结果感到非常失望: Chrome:~90 FPS Firefox:~25 FPS iPhone:~11 FPS

这是一个非常简单的测试,所以我不喜欢实际制作完整游戏的机会。这是canvas元素的标准结果还是有一些技巧可以让绘图更快,如果你有任何好的链接让我知道?帆布在这一点上只是一个玩具,还是可以用于现实世界的应用。

编辑 这是代码:

var ctx;
var width;
var height;
var delta;
var lastTime;
var frames;
var totalTime;
var updateTime;
var updateFrames;
var creats = new Array();

function init() {
    var canvas =document.getElementById('main');
    width = canvas.width;
    height = canvas.height; 
    ctx = canvas.getContext('2d');
    for(var i=0; i < 100; ++i) {
        addCreature();
    }
    lastTime = (new Date()).getTime();
    frames = 0;
    totalTime = 0;
    updateTime = 0;
    updateFrames =0;
    setInterval(update, 10);
}


function addCreature() {
    var c = new Creature(Math.random()*100,Math.random()*200);
    creats.push(c);
}

function update() {
    var now = (new Date()).getTime();
    delta = now-lastTime;
    lastTime = now;
    totalTime+=delta;
    frames++;
    updateTime+=delta;
    updateFrames++;
    if(updateTime > 1000) {
        document.getElementById('fps').innerHTML = "FPS AVG: " + (1000*frames/totalTime) + " CUR: " + (1000*updateFrames/updateTime);
        updateTime = 0;
        updateFrames =0;
    }

    for(var i=0; i < creats.length; ++i) {
        creats[i].move();
    }

    draw();
}

function draw() {
    ctx.clearRect(0,0,width,height);
    creats.forEach(drawCreat);
}

function drawCreat(c,i,a) {
    if (!onScreen(c)) {
        return;
    }
    ctx.fillStyle = "#00A308";
    ctx.beginPath();
    ctx.arc(c.x, c.y, 10, 0, Math.PI*2, true); 
    ctx.closePath();
    ctx.fill();
}

function onScreen(o) {
    return o.x >= 0 && o.y >= 0 && o.x <= width && o.y <=height;
}

function Creature(x1,y) {
    this.x = x1;
    this.y = y;

    this.dx = Math.random()*2;
    this.dy = Math.random()*2;

    this.move = function() {
        this.x+=this.dx;
        this.y+=this.dy;
        if(this.x < 0 || this.x > width) {
            this.dx*=-1;
        }
        if(this.y < 0 || this.y > height) {
            this.dy*=-1;
        }
    }

}

init();

12458
2017-09-10 12:13


起源

你可以发布代码吗? - Castrohenge
我读到断开操作与DOM的连接会产生一些问题 真 更快,我认为他们制作了一个画布元素,没有将它连接到DOM树中的任何地方,并在绘制完成时将其打开。但我不是百分百肯定 - 我只是快速浏览了一篇文章,并认为这不是我现在所搜索的内容。 - Frank
我和你一样有同样的问题(和相同的目的,构建基于HTML Canvas的游戏在iOS和Android平板电脑和手机上部署它们)看看我的测试(天空和云,基本上是一堆圆圈移动) gubatron.com/html5/sky.html  我在桌面上获得了很棒的FPS,但是我能在Galaxy Tab上获得的最好的是10-12FPS。一直在尝试很多事情,唯一有帮助的是减少被绘制的圆圈数量。这让我想到,也许我应该在画布的一小部分上以更低的分辨率工作,然后将其缩小,那会飞吗? - Gubatron
我放弃了为手机制作基于画布的游戏,然后又回到制作应用程序。以较低的分辨率绘图会提高你的速度,但你会失去质量。我认为任何需要完整重绘每一帧的东西都无法在移动设备上运行。 - skorulis


答案:


为了使动画效率更高,并使帧速率与UI更新同步,Mozilla创建了一个 mozRequestAnimationFrame()函数 旨在消除setTimeout()和setInterval()的低效率。此技术后来仅被Webkit用于Chrome。

在2011年2月 Paul Irish发布了一个垫片 创建了requestAnimFrame(),之后不久 乔兰伯特扩展了它 通过恢复“超时”和“间隔”延迟来减慢动画节拍。

无论如何,我已经使用过两者,并且在Chrome和Firefox中看到了非常好的结果。如果支持requestAnimationFrame()不可用,则垫片也会回退到setTimeout()。 Paul和Joe的代码都在线 在github

希望这可以帮助!


6
2017-07-11 18:34



我应该澄清一下,在将它应用到你的代码后,我得到了60fps的chrome和firefox。这60fps是故意的,因为它将帧更新与UI更新同步。有关正确的技术解释,请参阅 nczonline.net/blog/2011/05/03/... - adamrmcd


它在很大程度上依赖于JavaScript引擎。 V8(Chrome)和Carakan(Opera)可能是生产质量最快的两款发动机。 TraceMonkey(火狐)和SquirrelFish(Safari)远远落后,KJS带来了后方。随着硬件加速进入主流,这将发生变化。

至于具体的优化,我们可能不得不看一些代码。请记住,画布支持合成,因此您实际上只需要重绘已更改的区域。也许您应该在没有画布的情况下重新运行基准测试,以便了解绘图操作是否真的是限制因素。

如果您想了解现在可以做些什么,请查看:
js1k
贝斯平
帆布斯坦 


5
2017-09-10 15:29



js1k让我觉得画布已经为主流做好了准备。仔细看看似乎有些人获得了非常好的表现而其他人没有做类似的事情。我使用console.prolfile()分析了我的代码。约90%的时间用于绘画。我可以使用堆肥获得一些额外的性能,但我必须编写一个管理器来确定需要重绘屏幕的哪些区域。这会增加很多复杂性 - skorulis


弧是绘制数学密集型的。您可以使用drawImage甚至putImageData而不是每帧绘制路径来显着提高性能。

图像可以是从URL加载的文件,也可以是通过在用户不可见的单独画布上绘制的图像(未连接到DOM)。无论哪种方式,您都将节省大量处理器时间。


2
2017-11-26 20:21





我写了一个简单的弹跳球,如果点击它就会给你点数。

它在Firefox,Safari,Chrome和iPad上运行良好。然而,iPhone 3G / 3GS的速度非常慢。我的旧手机也是如此。

对不起,我确实缺少具体数字。


1
2017-09-10 12:23





到目前为止,Chrome浏览器是我见过的唯一具有高帧率结果的浏览器。

您可能还想尝试最新的IE9预览版。这应该为您提供一个关于下一代浏览器(HTML5的硬件加速)如何处理您的代码的良好基准。

到目前为止,我已经看到IE9,Chrome 7和Firefox 4都将采用某种形式的硬件加速。


0
2017-09-10 12:17



我知道浏览器越来越好但移动设备呢?这是我想要定位的主要内容之一。如果我不得不等待3到5年才能让相当数量的人能够运行它,那就没有意义了。 - skorulis
那么,你期待什么?你将不得不在你的iPhone上添加一块GeForce卡来加快这一速度(我必须说,我很想看到这张照片)。顺便说一下:Chrome和iPhone使用相同的渲染引擎。你看到的只是计算能力的差异。 - Boldewyn


Canvas绘图需要进行大量优化。

你有可以分享的示例代码吗?


0
2017-09-10 14:22