javascript - 无法从内存中删除已创建但从未附加到页面的 Canvas 元素

标签 javascript canvas

我正在创建一个像这样的 Canvas 元素:

var canvas = document.createElement('canvas');

我使用这个 canvas 对象来获取上下文,并从那里使用上下文中的信息进行进一步的逻辑。

var context = canvas.getContext('2d');

...

// More logic

我从不将 canvas 元素附加到文档或任何其他元素,但使用 safari devtools -> Canvas 选项卡,我可以看到只要运行此代码,就会不断创建 canvas 元素。它们每个大约 200KB,并且在一个 session 中可以创建数百、数千个这样的 Canvas 元素。如果重新加载页面,它们将从内存中删除,并且不再出现在 Canvas 选项卡中。

但是,如果页面未重新加载且 Canvas 不断累积,您会发现性能有所下降。

那么,如果这些 Canvas 元素从未附加到页面中,我该如何从内存中删除它们呢?

请参阅下面的 Canvas 选项卡图片(仅适用于 Safari,因为较新版本的 Chrome 和 Firefox 不支持)。第一个 Canvas 对象是预期的,其他的我想删除。我正在使用 javascript 和 jquery。

enter image description here

最佳答案

问题来自于 Canvas 开发工具
它是保留对这些 Canvas 元素的引用并阻止垃圾收集器正确工作的罪魁祸首。

作为证明,请尝试运行以下代码片段,首先关闭开发工具,然后在“ Canvas ”选项卡上打开它。

var canvas, context;
for (let i=0; i<100; i++) {
  canvas = document.createElement( 'canvas' );
  canvas.width = canvas.height = 5000;
  context = canvas.getContext( '2d' );
}
console.log( 'done' );

当开发工具关闭时,它可以在 Safari 上无缝运行。
在出现“完成”消息后打开它,将显示页面上有一个 Canvas 处于事件状态。

Screenshot taken from my Safari 12.1.2 showing a single active canvas

但是,当开发工具打开时,它将开始卡顿,直到控制台中出现一些消息。

"[Warning] Total canvas memory use exceeds the maximum limit ..."

在 Canvas 面板中,我们将在此消息弹出之前生成的所有内容标记为事件状态。

Screenshot taken from my Safari 12.1.2 showing several active canvases


因此,为了避免这种情况,请避免在该工具打开时创建太多 Canvas 。

请注意,根据this answer ,最初由用户 minimo 提出,在使用后设置 Canvas 的 widthheight 属性将最大限度地减少此问题,这是非常有意义的,因为现在浏览器只有 0 x 0px 缓冲区可以保存在内存中.

关于javascript - 无法从内存中删除已创建但从未附加到页面的 Canvas 元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58438276/

相关文章:

Javascript 正则表达式不匹配

javascript - 3d基础知识绘制魔方

canvas - Flot 渲染 png 图像的背景颜色与浏览器中的背景颜色不同

javascript - 使用 javascript 修改超过 1 个 css 文件

javascript - 如何使用 Jasmine (Angular js) 对自定义装饰器进行单元测试

javascript - 如何清除关闭的 RTCPeerConnection >> [使用解决方法]

javascript - 在嵌套的对象数组中查找数组

javascript - 如何修复getimagedata操作不安全的问题

javascript - canvas.toDataURLWithMultiplier 不是一个函数

javascript - 如何在 html 5 Canvas 上旋转单个对象?