【问题标题】:Poor Canvas2D performance with Firefox on Linux在 Linux 上使用 Firefox 时 Canvas2D 性能不佳
【发布时间】:2013-01-07 08:34:09
【问题描述】:

在使用 Canvas2D 进行一些非常密集的渲染时,我遇到了一些特别难以调试的问题。我使用了各种各样的东西,从 globalCompositeOperation 到多个屏幕外画布,中间还有一些 drawImage 魔法。

它在 :

上运行得非常好和流畅
  • Chrome (26) [OSX 10.7.5]
  • Safari (6.0.2) [OSX 10.7.5]
  • Firefox(18 和 20 Aurora)[OSX 10.7.5]
  • Chrome (24) [Windows 7]
  • Firefox (12) [Windows 7]
  • Chromium (24) [Archlinux,Gnome 3]

编辑:添加了针对 Windows 7 的测试。奇怪的是,它适用于 FF12(我的双启动时有一个旧版本),但升级到 FF18 后性能肯定会受到影响。它在 Windows 上并不像在 Linux 上那么糟糕,而且 OSX 上的相同版本也可以完美运行。可能是回归?

由于某种原因,在 Firefox 和 Linux 上(我尝试了 18 和 20 Aurora),同时拖动和渲染时渲染性能很差。

如果我触发后忘记动画,它与 Chrome/Safari 相当,但如果我拖动并渲染,我通常在释放拖动后只能看到结束帧。

  • requestAnimationFrame 和鼠标事件处理程序上的直接渲染都不起作用。
  • 分析后,渲染部分的报告时间完全在可接受的范围内(绝对最差可达 100 毫秒),并且绝对与我在屏幕上看到的不对应。
  • 我尝试通过删除一些东西来减少负载,最终报告的渲染时间低于 15 毫秒,但我看到的并没有改变。

让我感到困惑的是,它几乎可以在 Linux 上使用 Firefox 的其他任何地方运行除了。关于我应该查看的位置、错误报告或问题的解决方案有什么想法吗?

【问题讨论】:

    标签: performance html canvas


    【解决方案1】:

    由于这个问题,我已完全切换到 Linux 上的 Chrome。它源于他们使用的名为 Cairo 的旧 2D 渲染引擎,该引擎陈旧且过时。 Azure 是要替换这个引擎,他们基本上已经完成了除了 linux 之外的所有平台。

    http://blog.mozilla.org/joe/2011/04/26/introducing-the-azure-project/ https://bugzilla.mozilla.org/show_bug.cgi?id=781731

    【讨论】:

      【解决方案2】:

      据此,我想我知道你应该看哪里:

      如果我触发后忘记动画,它与 Chrome/Safari 相当,但如果我拖动并渲染,我通常在释放拖动后只能看到结束帧。

      可能是 Firefox 在 linux 上的双缓冲错误。

      Canvas 实现内置了双缓冲。您可以在任何浏览器上看到它在如下一个简单示例中的作用:http://jsfiddle.net/simonsarris/XzAjv/(它使用 setTimeout 与额外的工作来说明清除不会正确发生离开)

      实现尝试通过将其渲染到内部位图来延迟所有渲染,然后一次性(在下一次暂停时)将其渲染到画布上。这会在重绘场景之前清除画布时停止“闪烁”效果,这很好。

      但似乎 Linux Firefox 中存在一个普通的老错误。在您的拖动和渲染过程中,它似乎没有更新画布,可能是为了缓冲,但似乎在不应该这样做的时候这样做。这可以解释为什么它可以在即发即弃的场景中发挥作用。


      所以我认为应该提交错误报告。我没有任何 linux 机器,所以我无法复制它并自己提交一些东西来确定,抱歉。


      这是对评论的回复:您可以在鼠标移动期间将绘图部分分配给一个微型计时器。

      例如:

      // The old way
      theCanvas.addEventListener('mousemove', function() {
        // if we're dragging and are redrawing
        drawingCode();
      }, false);
      
      // The new way
      theCanvas.addEventListener('mousemove', function() {
        // if we're dragging and are redrawing
      
        // in 1 millisecond, fire off drawing code
        setTimeout(function() { drawingCode(); }, 1);
      }, false);
      

      没有这样的方法,它完全隐藏。你可以做的是,在鼠标移动期间,调度

      【讨论】:

      • 我认为这也与双缓冲有关。我尝试在 2D 上下文对象中寻找可以立即刷新/交换前/后缓冲区的方法,但没有找到任何东西。你知道我是否忽略了一个吗?
      • 我在this 错误报告上添加了评论。与此同时,我会接受你的回答。如果他们有其他信息,我会更新问题。
      • 不幸的是没有这样的方法,缓冲对用户完全隐藏。我在使用非常小的计时器来解决其他部分画布应用程序中的问题方面取得了一些成功。我编辑了答案以显示一个小例子,请看一下
      • 嗯,这似乎是个好主意,我会研究一下!与此同时,仍在等待有关错误报告的答案。希望 Firefox 团队的某个人会为 Firefox 20 修复它。这意味着我的工作量会减少;)
      • 顺便用Aurora试过了吗?如果它出现在夜间,可能值得一看
      猜你喜欢
      • 1970-01-01
      • 2014-05-12
      • 1970-01-01
      • 2011-05-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-01
      相关资源
      最近更新 更多