【问题标题】:javascript dom insertion. Performance vs Leak?javascript dom 插入。性能与泄漏?
【发布时间】:2009-10-16 12:43:41
【问题描述】:

我想知道 dom 插入复杂元素的正确方法是什么。

直到现在,(使用 jQuery)我通常先构建我的元素并在完成后插入它。我认为这是最有效的,因为 DOM 访问在性能方面代价高昂。

但是对于原生 js,我读到为了避免内存泄漏,每个新的 dom 节点都应该在创建后立即插入到 dom 中。

我们的内网说:

Dom 插入顺序 注意 DOM 插入顺序:永远不要在根元素本身附加到 DOM 之前将子元素附加到根元素。

var root = document.createElement("DIV");
var child = document.createElement("DIV");

// THIS IS WRONG

root.appendChild(child);
document.body.appendChild(root);

// THIS IS CORRECT

document.body.appendChild(root);
root.appendChild(child);

我在网上找到了这个页面,它基本上解释了同样的事情(在跨页泄漏部分下): http://www.codeweblog.com/javascript-memory-leak-on-the-collation-of-draft-issues/

这是否意味着性能和防泄漏之间存在对立?

在插入之前是否应该创建新的 DOM 元素并将其作为字符串操作? js 库是如何解决这个问题的? DocumentFragments 是奇迹解决方案吗?

【问题讨论】:

    标签: javascript jquery dom


    【解决方案1】:

    根据yui网站上的介绍,使用innerHTML = 'html here'是插入html最有效的方式。这是因为浏览器经过优化,可以非常快速地解析 HTML,而 DOM 作为标准,被认为是有缺陷的,并且在 IE 等浏览器中处理不当。

    因此,为了快速,innerHTML 是要走的路,我不认为它们是内存泄漏,因为它与用于解析 html 并在加载时呈现页面的引擎相同。

    【讨论】:

      【解决方案2】:

      您引用的建议几乎肯定是受到 IE 团队成员关于memory leaks in (unsurprisingly) IE 的一篇文章的启发,特别是关于“DOM 插入订单泄漏模型”的部分。 有两点值得注意:

      1. 这篇文章写于 2005 年,专门用于解决 IE 6 中的泄漏问题 - 当时 IE 7 甚至还没有发布;
      2. 仅与 IE 相关;没有迹象表明任何其他浏览器也会遇到同样的问题。

      根据a 2008 post on the IE Team blog(在“内存管理改进”子标题下),IE 7 包括改进以防止此类泄漏在浏览器窗口的生命周期内持续存在,而 IE 8 包含进一步改进,希望消除任何需要关注的问题关于这件事。

      所以您需要问的问题是:IE 6 对您来说有多大的问题?归根结底,DOM 插入的顺序不应该是值得关注的事情,但是如果(例如)您正在开发一个将在 IE 6 上使用一段时间的 Intranet 应用程序,那么您应该请注意 2005 年文章中的要点。如果您有幸知道 IE 6 对您的应用程序来说几乎不是一个亮点,那么请不要担心。

      哦,请注意将所有内容附加到父级之前将父级附加到页面将提供更好的性能:每次添加新子级时都不必进行重排和重新绘制,浏览器可以进行一次重排和重绘,当所有内容都集中到一个整洁的块中时。

      【讨论】:

      • 我非常关心 IE7,它是我支持的最明智的浏览器。我们不支持 IE7。因此,如果泄漏不在 IE7 中,我很好,我可以继续使用我一直使用的方法。 IE7 是完全没有此类泄漏还是仅在这方面有所改进?
      • @Olivvv:如果我对博客文章的理解正确,当用户停留在一个页面上时仍然会有泄漏,但是当导航到另一个页面时它们会得到解决(或者,大概是重新加载现有页面)。如果您的交互模型依赖于停留在一个页面上并长期广泛地操作 DOM,那么您应该注意本文中描述的问题。但是,如果您只进行相对少量的 DOM 操作并结合导航到其他页面,那么这应该不是问题。
      • 是的,它是一个单页 web 应用程序,每天只加载一次。因此,即使是轻微的内存问题也是明智的。我想我下周得花些时间来设置测试。然后我会在这里发布结果。
      • 所以我做了一个简单的测试页面。我没有发现任何情况下 IE7 使用该方法出现内存泄漏。这是我的测试:jsbin.com/ajexe/edit
      【解决方案3】:

      在将子级插入到文档中之前将其插入到父级中没有任何问题。这是首选方式(正如您所建议的,出于性能原因)

      您指定的链接表明它会导致泄漏,但我从未听说过。他们没有很好地解释为什么会泄漏。

      如果确实泄漏,它肯定只会在 IE6 中泄漏,我建议你忽略它,因为它的市场份额一直在缩小。防止 IE6 中的泄漏可能是一项艰巨的工作,而且不值得。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-05-29
        • 2011-11-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-09-17
        相关资源
        最近更新 更多