使用JavaScript交换DOM元素,用于内存密集型应用程序

时间:2013-09-03 14:07:54

标签: javascript html dom memory

我想确保在以下情况下我不会遇到任何内存问题。

我准备创建一个使用许多不同交互式屏幕的应用程序。将需要在屏幕之间维护许多全局对象。这意味着对整个应用程序使用单个页面。每个屏幕都包含高分辨率图像和许多交互式控件。

当显示新屏幕时,我想确保从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

1 个答案:

答案 0 :(得分:1)

实际上,代码中最有趣也最琐碎的部分是start方法。没有它,它看起来不错,除了kill功能 - 它就像在黑暗的房间里拍摄一样)你无论如何覆盖你的this.screen属性,所以旧的引用应该被删除,以防你没有您start方法中的内存泄漏。

所以interactivity所有人都有风险。这可能是一些jQuery小部件或其他一些东西,它们保存对节点的引用,因此它们不会被垃圾收集器从内存中删除。这甚至可以是原始事件侦听器,也可以是带有DOM节点引用的封闭闭包。但是你的武器库中有一把好武器 - Memory TimelineHeap Profiler。过程很简单:打开第一个屏幕→收集内存分配的统计信息→转到下一个屏幕→强制执行垃圾收集器→测量和比较内存。