Html5 Canvas“复合层”导致长帧

Posted

技术标签:

【中文标题】Html5 Canvas“复合层”导致长帧【英文标题】:Html5 Canvas "Composite Layers" causing long frames 【发布时间】:2017-01-12 09:36:24 【问题描述】:

我有一个在网页上运行的 javascript 客户端,使用 requestAnimationFrame 绘制到画布并通过 websockets 与我的 NodeJS 后端服务器通信(使用“ws”服务器端的模块)。

使用 Chrome DevTools 进行分析,似乎脚本、渲染和绘制每一帧的总时间最多只有几毫秒。然而仍然存在卡顿——从 20 到 40 毫秒的长帧。

时间线显示,在几乎所有这些情况下,都存在超过帧长度的“响应”和/或发生了“复合层”也接近尾声。

这基本上就是我使用 requestAnimationFrame 的方式:

function drawGame() 

    // Drawing to gameCanvas from cacheCanvas
    // cacheCanvas is updated whenever an update is received from the server

    ctx.drawImage(cacheCanvas,
        // source rectangle
        0, 0,
        gameCanvas.width*2, gameCanvas.height*2,

        // destination
        100, 100,
        gameCanvas.width*2, gameCanvas.height*2
    );

    requestAnimationFrame(drawGame);


requestAnimationFrame(drawGame);

服务器使用 setInterval() 以 60hz 发送更新。当从服务器接收到消息时,客户端立即绘制它。我怀疑这个时间与 requestAnimationFrame 结合可能不正确,并导致帧末尾的复合层。

即便如此,我还是很困惑,为什么在每个帧的脚本编写和“复合层”之间有这么多空闲时间。 所以...

有没有办法控制何时调用“复合层”?

我是否应该保存每个更新消息中的数据,并且只在下一个动画帧的开头绘制它?

“响应”指的是什么?

谢谢!

【问题讨论】:

我现在遇到了这个问题,你找到原因了吗?我正在使用 Chrome Canary 版本 65.0.3322.3 (Official Build) canary (64-bit) 【参考方案1】:

Chrome 的版本、渲染选项和视频驱动程序都可能会影响这一点。将这些信息与您的问题一起发布。也可以尝试在 Chromium 错误列表中搜索。

您也可以尝试最新的 Firefox 开发版本,它应该通过使用多个进程来获得更好的性能。

要确定服务器响应等是否与性能有关,请将其删除并使用来自客户端的虚假数据仅作为测试。

【讨论】:

以上是关于Html5 Canvas“复合层”导致长帧的主要内容,如果未能解决你的问题,请参考以下文章

Html5之canvas重叠矩形getContextfillStylefillRect

Html5之canvas笑脸getContextbeginPathmoveToarcstroke

Html5之canvas清除特定矩形getContextfillStylefillRectclearRectstrokeRect

Html5之canvas三角形getContextbeginPathmoveTolineTofillclosePathstroke

HTML5自学笔记[ 24 ]canvas绘图之星空草地

canvas设置长宽