我想确保在以下情况下不会遇到任何内存问题。
我正准备创建一个将使用许多不同交互式屏幕的应用程序。将有许多全局对象需要在屏幕之间进行维护。这意味着对整个应用程序使用单个页面。每个屏幕都包含高分辨率图像和许多交互式控件。
显示新屏幕时,我想确保从 RAM 中删除前一屏幕的图像。这意味着将它们从 DOM 中移除并删除对它们的任何 JavaScript 引用。
我想出了以下技巧:
* 每个屏幕由不同的 JS 文件表示。
* 每个JS文件都包含一个构造函数:Screen1()、Screen2()等。
* 结果对象有一个返回 HTML 字符串的方法。它也可能有一个返回自定义 css 文件 url 的方法。
* 为了跳转到一个新的屏幕,Swap 对象会销毁当前的 Screen 对象,并用适当的构造函数创建的新对象替换它。
* 然后 Swap 对象设置页面主体的 innerHTML。它还可以为当前屏幕交换自定义 css 文件。
* Swap 对象然后调用当前 Screen 对象中的 start() 方法,以初始化所有交互。
jsFiddle 不乐意模拟这个,所以我创建了两个链接供您测试:
演示:http://openbook.lexogram.com/proto/swap/
来源:http://openbook.lexogram.com/proto/swap.zip
我的问题:
1. 这种做法有没有明显的缺陷?
2. 这个问题是否已经用更传统的方法解决了?
下面是一段代码,可以让您了解它的工作原理:
// SWAP OBJECT //
function Swap(container, constructor) {
this.container = container
this.in(constructor)
}
Swap.prototype.in = function screen(constructor) {
if (this.screen) {
this.kill(this.screen)
delete this.screen
}
this.screen = new constructor()
this.container.innerHTML = this.screen.html()
this.screen.start()
}
Swap.prototype.kill = function kill(object) {
for (key in object) {
delete this[key]
}
}
var swap
document.addEventListener('DOMContentLoaded', function() {
var body = document.getElementsByTagName("body")[0]
swap = new Swap(body, Screen1)
swap.in(Screen1)
});
// SCREEN1 (in a different js file) //
function Screen1() {}
Screen1.prototype.html = function getHTML() {
return "<div id='screen1'>"+
"<p>Click anywhere to go to Screen 2</p>"+
"</div>"
}
Screen1.prototype.start = function startScreen1() {
this.link = document.getElementsByTagName("body")[0]
this.link.onclick = function showScreen2(event) {
swap.in(Screen2)
}
}
// SCREEN2 not shown, but similar
最佳答案
实际上,代码中最有趣也最危险的部分是 start
方法。没有它,它看起来不错,除了 kill
功能 - 它就像在黑暗的房间里拍摄)无论如何你覆盖你的 this.screen
属性,所以旧的引用应该是然后删除,以防您的 start
方法中没有内存泄漏。
所以你所有的交互
都是有风险的。这可能是一些 jQuery 小部件或其他东西,它们保存对节点的引用,因此它们不会被垃圾收集器从内存中删除。这甚至可以是原始事件监听器,或者一些带有 DOM 节点引用的封闭闭包。但是你的武器库里有一把好武器 - Memory Timeline , Heap Profiler .过程很简单:打开您的第一个屏幕 → 收集内存分配的统计信息 → 转到下一个屏幕 → 强制垃圾收集器 → 测量和比较内存。
关于javascript - 使用 JavaScript 交换 DOM 元素,用于内存密集型应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18594426/