为许多图像优化 Konva.js

ros*_*res 3 javascript png html5-canvas konvajs electron

我目前正在使用 Konva.js 在几个堆叠的 FastLayers 上平铺许多 PNG 图像。PNG 包含不透明度,它们不需要拖动或命中框。瓷砖经常更换,这似乎适用于尺寸约为 30x30 的中型网格。一旦磁贴开始增长到 100x100 左右,甚至 60x60,在替换单个磁贴时性能开始变慢。

我已经开始研究“分块”拼贴,即将拼贴添加到较小的 FastLayer 组中。例如,单个 100x100 FastLayer 将被划分为多个 10x10 FastLayers。当单个 tile 发生变化时,我们的想法是只有那个块应该重新渲染,理想情况下可以加快整体渲染时间。

这是一个值得尝试的好设计,还是我应该尝试不同的方法?我查看了 Konva.js 文档中的性能提示,但没有看到任何与此案例直接相关的内容。

ros*_*res 6

因此,经过一些研究和修补,我发现了渲染约 4000 张图像的最快方法。

  • 不要为 Konva.js 使用 React 组件。我使用 React 来构建我的应用程序,但我跳过了使用 Konva.js 渲染的中间库。在画布上使用 React Components 会使你的性能减半。
  • 缓存常用图像。我使用一个简单的 LRU 缓存来重用 HTMLImageElement 对象。
  • 尽可能重用 Konva.js 节点 (Konva.Image)。我的实现是渲染图像网格。位置不会改变,但图像可能会改变。之前,我会 destroy() 一个节点,然后添加另一个。destroy() 会导致额外的渲染,这会为您的用户造成卡顿。相反,我只是将 image() 方法与 id() 和 name() 结合使用来查找和替换网格坐标处的图像。
  • 我的应用程序允许用户在网格上绘制长笔画。当仅使用文字鼠标事件时,这在小笔画中可以正常工作。对于长行程,这不起作用有两个原因。首先,操作系统和浏览器会限制鼠标事件,为您提供间歇性鼠标事件。其次,在渲染中间会产生相同的副作用。相反,该软件现在检测长笔画,并“填充”用户打算在间歇性鼠标事件之间绘制的缺失坐标。
  • 间隔渲染。由于我的网格可以经常更改,我决定每秒对网格信息采样 24 次,而不是让每个 tile 更改排队一个 batchDraw()。底层实现是使用 RxJS 每 42 毫秒轮询一次 Redux 存储,并且仅在发生更改时才将 batchDraw() 排队。