Canvas 重新绘制卡住(性能问题)

Canvas re-drawing gets stucked (performance-problem)

我要为我的 Raspi 项目创建一个 GUI。 Raspi3 上有 Nodejs 运行,它运行一个 NodeJs-Server,然后在 kiosk 模式下用 Chromium 请求它。

此 GUI 的一页需要可视化 48 个电位器、12 个按钮、8 个推子的状态。 NodeJs-Server 通过 websocket 向客户端发送数据(被用户修改),客户端重绘整个 canvas。到目前为止,一些元素工作正常:

works fine but with a slight delay if you look closer

现在问题是,随着需要绘制的元素数量的增加,性能下降到无法接受的延迟时间。

works, but with a way too big dalay, as more elements are drawn

这些甚至还不到需要绘制的一半。

我现在很困惑,因为在我决定走那条路之前,我读到了 canvas 有多快,如果我停用所有 canvas-绘图并简单地 console.log()通过 websocket 传入的数据,它像实时一样快。

所以我做错了什么?也许最好不要在每次值更改时绘制整个 canvas,而是为 canvas 设置动画?也许有人对此有经验?

Here is the code.. 当您查看 assets/js/menu.class.js 时,这是生成 canvas 的文件。每次值更改时,函数 createControllerGUI(options) 都会通过 websocket 调用。

Canvas 很快,但仍然 cpu 密集。速度也随着平台的变化而变化。

您的函数执行每次更改的所有绘图操作。这些操作有描边、填充、居中对齐的文本等等(我没有仔细看)。

有一些方法可以优化绘图操作。

部分重绘

也许是最有效的。 跟踪小部件的位置,跟踪消息之间更改的数据并仅绘制差异。 在小部件占用的区域上使用 clearRect 并重绘它。不要触摸其他像素。 除非章鱼正在使用硬件,否则每帧最多会更改 2 或 3 个小部件。

一下子划完。

您可以一次跟踪所有需要的路径,而不是在每个小部件的基础上进行描边,在更改小部件时使用 moveTo 到新位置,并在循环结束时使用单个描边操作。

缓存

例如,如果您有一些旋转控件,您可以在一个小的单独 canvas 上绘制一次它们,然后使用该 canvas 作为源图像以不同的角度绘制,如果您需要表示一个旋转的控件。 DrawImage 通常使用硬件操作进行优化,而单个填充和描边可能不会。

可能还有其他方法,您可以查看可以为您执行此操作的高级库,公开小部件逻辑而不是低级绘图操作。