【发布时间】:2013-08-01 15:02:44
【问题描述】:
众所周知,如果您在 flash 元素之上有 html 元素(例如带有列表的模态窗口),您会遇到巨大的性能问题导致 flash 导致浏览器在 flash 上重新绘制任何 html动画。我想知道如果您在动画画布元素之上有 html 元素,是否也会发生同样的情况。
我问这个是因为我正在构建一个画布游戏,我想知道使用 DOM 制作 GUI(菜单、导航按钮等)而不是在画布上绘制是否是个好主意。
【问题讨论】:
众所周知,如果您在 flash 元素之上有 html 元素(例如带有列表的模态窗口),您会遇到巨大的性能问题导致 flash 导致浏览器在 flash 上重新绘制任何 html动画。我想知道如果您在动画画布元素之上有 html 元素,是否也会发生同样的情况。
我问这个是因为我正在构建一个画布游戏,我想知道使用 DOM 制作 GUI(菜单、导航按钮等)而不是在画布上绘制是否是个好主意。
【问题讨论】:
我刚刚使用 Chromium 版本 28.0.1500.45 Mageia.Org 3 (205727) 进行了测试,并且在我的画布动画时不会重新绘制元素。
我尝试了this 带有 DIV 的简单框动画。之后,我分析了我的应用程序以查看发生了什么。我注意到只有画布被重新粉刷。
window.requestAnimFrame = (function(callback) {
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame ||
function(callback) {
window.setTimeout(callback, 1000 / 60);
};
})();
var GX = 0;
function animate() {
var canvas = document.getElementById('jaja');
var context = canvas.getContext('2d');
// update
GX += 10;
if (GX > 500) GX = 0;
// clear
context.clearRect(0, 0, canvas.width, canvas.height);
// draw stuff
context.beginPath();
context.rect(GX, 10, 100, 100);
context.fillStyle = '#8ED6FF';
context.fill();
context.lineWidth = 1;
context.strokeStyle = 'black';
context.stroke();
requestAnimFrame(function() {
animate();
});
} // request new frame
接下来,我尝试通过选择文本来重新绘制 DIV。这次是的,DIV 重新绘制了。
这是profile 的屏幕截图。
1:我们可以在每次制作动画时调用 Paint (600x586)。
2:只有当我选择文本时,它才会为 DIV 元素调用 Paint。
我个人不相信任何其他浏览器会有与此不同的行为。
【讨论】:
是的,将其他 DOM 元素放在画布元素之上会降低其性能。
这是因为浏览器在更新画布/绘画时必须进行额外的剪辑。
画布需要每秒更新 60 次才能输出到屏幕。如果有东西在上面,它需要被剪掉很多次。如果 DOM 元素也被重新绘制,那么将取决于浏览器,但 canvas 元素本身的性能会降低。
通常 DOM 绘制发生在单个线程中(但对于大多数主流浏览器来说即将发生变化),因此如果该线程上有额外的负载,它也会影响其他正在绘制的东西。
还有 JavaScript 的单线程,这是更新画布所必需的。如果画布的性能低于执行其更改(以及对 DOM 的更改)的脚本,也会受到影响。
【讨论】: