【问题标题】:Swap out DOM elements with JavaScript, for memory intensive application使用 JavaScript 替换 DOM 元素,用于内存密集型应用程序
【发布时间】:2013-09-03 14:07:53
【问题描述】:

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

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

当显示一个新屏幕时,我想确保前一个屏幕中的图像已从 RAM 中删除。这意味着将它们从 DOM 中移除并删除对它们的任何 JavaScript 引用。

我想出了以下技巧:
* 每个屏幕由不同的 JS 文件表示。
* 每个 JS 文件都包含一个构造函数:Screen1()、Screen2() 等。
* 结果对象有一个返回 HTML 字符串的方法。它也可能有一个返回自定义 css 文件的 url 的方法。
* 要跳转到新屏幕,Swap 对象会破坏当前屏幕对象,并将其替换为由相应构造函数创建的新对象。
* 然后 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

【问题讨论】:

  • 你没有你认为的控制水平。操作系统、浏览器和下划线软件控制内存使用,而不是您。您可以使用delete 取消设置引用并希望浏览器按您希望的方式处理。
  • 当然。我明白那个。我想确保我采用的方法不会妨碍浏览器尽可能地进行清理。是的,我的 Swap 对象使用delete 来终止引用。
  • 那么这就是你所能做的。之后由浏览器和操作系统来正确释放资源并且不会发生内存泄漏。
  • 你是在暗示我的方法是矫枉过正吗?是否有一种更简单、更好记录的方法来处理包含许多我忽略的高分辨率图像的单个页面?
  • 我是说如果你成功地使用了delete,那么你已经走到了尽头。一旦你删除了它,就真的没有更多的事情要做了。我建议在您的情况下使用尽可能少的库以降低开销。

标签: javascript html dom memory


【解决方案1】:

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

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

【讨论】:

    猜你喜欢
    • 2010-10-25
    • 2011-01-08
    • 1970-01-01
    • 2010-12-09
    • 1970-01-01
    • 2013-04-10
    • 1970-01-01
    • 2012-07-07
    相关资源
    最近更新 更多