有没有办法重用 ImageData 来减少 GC activity?

Is there a way to reuse an ImageData to reduce GC activity?

我正在寻找一种 GC 友好的方式来使用 CanvasRenderingContext#getImageData。一个想法是创建一次 ImageData 并以某种方式重用它,这样 getImageData 就不会分配新的。因为我需要每秒访问原始 canvas 数据大约 60 次,所以每次使用 getImageData 时我真的负担不起分配一个新的 ImageData。这可能吗?

如果您需要使用缓冲区的数据操作 + putImageData 以外的任何其他方式进行绘制,则不需要。

ctx.getImageData() 返回的 ImageData 对象是底层 canvas' 缓冲区的 copy,它不以任何方式链接到该内部缓冲区,并且对 canvas 的任何更新都不可能对返回的 ImageData 进行任何更改。

请注意,active discussions 关于从 canvas API 到 WebAssembly 的零复制。一个想法是扩展 getImageData(),这样它“ 可以查看哪些字节可以写入 ”。但这只是在讨论阶段,我们可能需要等待一段时间才能看到针对这个越来越普遍的问题的可行解决方案。

如果您在更改 ImageData 中的数据后仅通过 ctx.putImageData() 进行绘制,那么您当然可以只保留相同的 ImageData 而不再请求任何新的,因为您的 ImageData 将始终可用迄今为止。

此外,ImageData 的一个非常常见的误用是当我们想将它发送给 WebWorkers 进行处理时,不要忘记使用 worker.postMessage() 的第二个参数来传输它,否则你会复制此数据在每条消息中。