【问题标题】:Why does filling in a rectangle on a canvas degrade performance slowly?为什么在画布上填充矩形会缓慢降低性能?
【发布时间】:2015-04-16 13:37:34
【问题描述】:

我目前正在开发一个使用 <canvas> 元素的 HTML5 游戏。随着时间的推移,我在程序中神秘地遭受性能下降,希望你能解释一下这种行为。

我已将问题追溯到绘制每一帧背景的函数。简而言之,它显示为:

function paintBackground() {
  ctx.rect(0, 0, canvas.width, canvas.height)
  ctx.fillStyle = "black"
  ctx.fill()
}

我还设置了一个 JSFiddle 来代表这种情况。

这段代码的有趣之处在于,在测量时,它的效率会慢慢降低几个数量级。以 JSFiddle 为例,它从函数开始,完成时间不到一毫秒。大约 2-3 秒后,它报告它现在需要大约 1 毫秒。大约 10 秒后,现在平均在 2-3 毫秒之间。在一分钟内,它平均大约需要 6-7 毫秒,当我让它运行大约 5 分钟时,它会达到 13-14 毫秒。这比开始时慢了数百%,没有任何变化!我在 IE 11 和 Firefox 35.0.1 中测试了相同的代码。两者都表现出相同的退化,但在 Firefox 中似乎下降得更快。

现在,我不是对微优化大惊小怪的人,但我的目标是达到稳定的 60FPS,这意味着我只有大约 16.67 毫秒的时间用于渲染和更新,而且我基本上逐渐失去了其中的一半通过渲染背景!我也担心这可能是一列失控的火车,谁知道性能会变得多么糟糕;可能会导致我的游戏无法玩。

据我所知,这是导致性能下降的唯一因素,原因有两个:1) 游戏代码的其余部分运行平稳,包括渲染所有瓦片(每帧 375 多个瓦片)组成一个关卡,并且 2) 我甚至在提供的 JSFiddle 中也遇到了这种行为,其中只包含矩形填充。

对此行为的任何解释或建议都会很有启发性!

附:我知道这听起来可能很愚蠢,但是还有其他人经历过这种行为吗?还是只有我?我应该注意到,虽然我的 CPU 足够慢(1.4ghz 双核),但这一点很明显。

【问题讨论】:

  • 确认在 IE11 和 Firefox 中降级,但在 Chrome 中没有。

标签: javascript html performance canvas


【解决方案1】:

rect() 命令将添加到路径中并累积,因此每次调用fill() 时,之前的所有矩形都会被填充。

以两种方式之一解决:

function paintBackground() {
  ctx.beginPath(); // RESET path here
  ctx.rect(0, 0, canvas.width, canvas.height);
  ctx.fillStyle = "black";
  ctx.fill();
}

或者不使用路径直接填充:

function paintBackground() {
  ctx.fillStyle = "black";
  ctx.fillRect(0, 0, canvas.width, canvas.height);
}

还可以使用 requestAnimationFrame 以获得更好的动画效果。

Modified fiddle

Ps:不要忘记半列。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-05
    相关资源
    最近更新 更多