HTML5 Canvas fillRect 慢

Posted

技术标签:

【中文标题】HTML5 Canvas fillRect 慢【英文标题】:HTML5 Canvas fillRect slow 【发布时间】:2013-08-12 15:19:39 【问题描述】:

我正在尝试使用 html5 画布编写一个简单的光线投射器,但帧速率非常糟糕。 Firefox 的分析器报告说我 80% 的运行时间都花在了 context2d.fillRect() 中,我在地板和天花板的每列以及纹理墙壁上的每个像素中都使用了它。我遇到了this 问题,发现fillRect 在chrome 上比1x1 px 图片快40%,在firefox 上快4%。他们提到它仍然在计算 alpha 的东西,尽管我假设如果 alpha 为 1,它会通过不透明渲染?是否有任何其他方法可以使用 javascript 进行大量矩形和像素位传输,我应该尝试一下?

【问题讨论】:

其实我觉得你应该试试WebGL。据我所知,WebGL 的硬件加速浏览器比 canvas 2d 多。 Canvas 2d 在浏览器中的性能还没有真正完善,它在不同浏览器之间存在很大差异。我相信它在未来会有所改善。但在那之前,我会说使用上面提到的 WebGL。我也相信它将完全取代 Flash。 现在的浏览器默认启用 webgl 吗?我一直在使用画布,希望有更好的兼容性 @zacaj 检查此website。他们有一个 webgl 兼容性列表。当然这并没有考虑到某些显卡被列入黑名单。 需要看一些代码。根据您的操作方式,createImageData + putImageData 比 fillRect 快 很多 这是一个显示超过 20k 个粒子的快速示例somethinghitme.com/projects/masspart 【参考方案1】:

我发现的一个解决方案是每次调用 fillRect() 时都将其放入路径中:

canvasContext.beginPath();
canvasContext.rect(1, 1, 10, 10);
canvasContext.fill();
canvasContext.closePath();

似乎对 rect() 的调用会添加到先前 rect() 调用的路径中,如果使用不当,可能会导致内存泄漏或资源使用量增加。

【讨论】:

fillRect 方法确实创建了一个临时 Path 对象,它不会向先前设置的路径添加任何内容,并且在您的代码中不需要 closePath() 调用 fill() + rect() 在我的 js 上运行分析器时占 ~30%,而仅执行 fillRect() 占 ~20%【参考方案2】:

您可以尝试两种解决方案来减少渲染的 CPU 使用率。

尝试使用 requestAnimationFrame 以便您的浏览器在准备就绪时渲染您的画布图形,尤其是仅当用户在浏览器中打开画布选项卡时。更多信息:https://developer.mozilla.org/en-US/docs/Web/API/window.requestAnimationFrame

第二种解决方案,取决于您的部分或全部内容是动态的,是使用 JavaScript 在内存中的其他“隐藏”画布上预渲染画布的一部分(例如,您将主画布分成 4 个子画布然后只需在屏幕上绘制 4 个元素)。

PS:如果你在 Mac 上使用 Firefox 结合多个画布渲染将比 Chrome 提高你的 CPU 使用率

希望对你有帮助

【讨论】:

以上是关于HTML5 Canvas fillRect 慢的主要内容,如果未能解决你的问题,请参考以下文章

HTML5之canvas-1画布矩形

html5中怎么根据内容高低来调整画布大小

canvas

HTML5 Canvas 上的富文本编辑

canvas之碎碎念

使用 canvas 绘图的几种方法