javascript - 为什么在 Canvas 上填充矩形会缓慢降低性能?

标签 javascript html performance canvas

我目前正在开发一款使用 <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) 游戏代码的其余部分运行平稳,包括渲染所有的图 block (每帧 375+ 个图 block )组成一个关卡,并且 2) 即使在提供的 JSFiddle 中,我也体验过这种行为,它只包含那个矩形填充。

任何关于这种行为的解释或建议都会很有启发性!

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

最佳答案

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:不要忘记半列。

关于javascript - 为什么在 Canvas 上填充矩形会缓慢降低性能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28534715/

相关文章:

c - 如何在考虑性能的情况下最好地用C编写体素引擎

python - 这些四叉树库中的任何一个都好吗?

javascript - VB.NET Web API CORS PUT 预检 405 错误

javascript - 添加 MVC ValidationMessageFor 以分隔 Div 标签

html - 针对移动设备和 CSS @font-face 进行优化

javascript - jQuery/javascript - 根据下拉选择更改图像

python - 为什么列表乘法这么快?

javascript - 如何在未选中复选框时删除值?

javascript--无法获取 [Object Text] 的 textContent?

javascript - jquery/javascript-给定周数和年数计算本周的天数