javascript - 无法从内存中删除已创建但从未附加到页面的画布元素
问题描述
我正在创建一个这样的画布元素:
var canvas = document.createElement('canvas');
我使用这个canvas
对象来获取上下文,并从那里使用上下文中的信息进行进一步的逻辑。
var context = canvas.getContext('2d');
...
// More logic
我从不将 canvas 元素附加到文档或任何其他元素,但使用 safari devtools -> Canvas 选项卡,我可以看到无论何时运行此代码,都会不断创建 canvas 元素。它们每个大约 200KB,在一个会话中可以创建成百上千个这样的画布元素。如果页面重新加载,它们将从内存中删除,并且不再出现在画布选项卡中。
但是,如果页面没有重新加载并且画布建立起来,您会看到性能下降。
那么,如果这些画布元素从未附加到页面,我该如何从内存中删除它们呢?
请参阅下面的画布选项卡图片(仅适用于 Safari,因为较新版本的 Chrome 和 Firefox 不支持它)。第一个画布对象是预期的,其他的我想删除。我正在使用 javascript 和 jquery。
解决方案
问题来自非常画布 dev-tool。
它是保持对这些画布元素的引用并阻止垃圾收集器正常工作的罪魁祸首。
作为证明,尝试运行以下代码段,首先关闭开发工具,然后在“画布”选项卡上打开它。
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 上无缝运行。
在“完成”消息出现后打开它会显示页面上只有一个画布处于活动状态。
但是,随着开发工具的打开,它会开始卡顿,直到控制台中出现一些消息。
“[警告] 总画布内存使用超过最大限制......”
在画布面板中,我们将在此消息弹出之前生成的所有内容都标记为活动状态。
因此,为避免这种情况,请避免在此工具打开时创建太多画布。
请注意,根据这个答案,正如用户minimo最初提出的那样,在使用后设置画布的width
和height
属性将最大限度地减少这个问题,这是非常有意义的,因为现在浏览器只有一个 0 x 0px 的缓冲区来保存在内存中。
推荐阅读
- assembly - 尔湾 x86 汇编输出
- java - Java 十六进制 velue 转换为 ascii 并返回十六进制出错
- java - 使用 java 处理 wsdl 模式中的“任何”字段
- marklogic - 在 Marklogic 9 中更新 MarkLogic 8 摄取的双时态文档
- angular - 组件是2个模块声明的一部分:AppModule
- javascript - 如何在 JS 中键入建议功能时触发搜索?
- asp.net-core - SignalR 干扰另一个控制器
- c# - UWP XAML:自定义画笔以将进度条绘制为网格背景
- azure - Azure SQLDatabase 安全 - 无法从门户中删除动态数据屏蔽规则
- css - 命名页面和弹性框在 PDFReactor 中不起作用