如何提高将文本插入HTML元素的性能?

时间:2011-01-19 17:33:31

标签: javascript jquery

在Firefox中,我使用以下代码将文本插入~500 DIV:

$(".divs").text("default"); // ~500 DIVs

在我的计算机上,如果DIV为空,则一直需要 9ms 。但是,如果DIV已经包含文本,则相同的代码始终需要 18ms

为什么空DIV在插入文本时要快2倍(jQuery是否需要先清空DIV)?并且,有没有办法提高替换已包含文本的DIV中的文本的性能?

注意:在IE 7中,速度差异并不那么显着。在空DIV中插入文本的速度提高了约1.5倍。

5 个答案:

答案 0 :(得分:6)

如果要插入的文字 NOT 需要转义,那么您可能需要尝试以下操作:

$(".div").each(function(){
  this.innerHTML = "default";
});

当您使用method .text()时,jQuery会对文本进行一些处理。

  

我们需要注意这个方法   转义提供的字符串   必要的,以便它将呈现   在HTML中正确。为此,它打电话   DOM方法.createTextNode(),   用...替换特殊字符   他们的HTML实体等价物(例如   < for<)。

修改 为了避免.each()方法的惩罚,您可以尝试以下方法:

var divs = $(".divs"),
    i = 0,
    len = divs.length;
while(len--) {
  divs[len].innerHTML = "default";
}

如果这不能让您获得任何性能提升,那么它绝对是一个浏览器实现问题。至少这将排除jQuery性能问题/错误。

答案 1 :(得分:6)

如果您想要所有浏览器的最快解决方案,请使用textContent(如果支持)并回退到innerText / innerHTML,否则 [Test] (知道 gotchas )。

/**
 * Replaces text for all elements in the given array.
 * @param {Array} elems
 * @param {String} text
 */
var replaceText = (function(){
  var dummy = document.createElement("div");
  dummy.innerHTML = "text";
  var TEXT = (dummy.textContent === 'text') ? 'textContent' : 'innerText';
  return function(elems, text) {
    for (var i = elems.length; i--;) {
      elems[i][TEXT] = text;
    } 
  };
})();

比jQuery文本更快

    在IE 8上
  • 4x
  • Firefox 4b11上的
  • 2.2x
  • Chrome上的
  • 1.3x

答案 2 :(得分:3)

是的,当元素具有子元素时,此方法的原因是因为jQuery的.text()方法首先运行.empty()方法然后.append(document.createTextNode(text))

来自jQuery.text

// ...
return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
// ...

我指出这一点的原因是.empty()方法调用.cleanData()方法删除与其子节点关联的任何数据和/或事件,然后执行标准{{1}在其所有子节点上删除它们的方法,这是已经包含文本的div更新速度较慢的主要原因。

你的问题的解决方案是编写自己的,vanilla,javaScript函数来更新div的文本,但要确保你没有通过jQuery将任何点击事件或数据附加到它们,因为你肯定会有一些内存泄漏。

答案 3 :(得分:3)

您可以通过重复使用现有文本节点来获得性能。

仅包含文本的DIV元素是一个DOM元素,它包含一个类型为文本节点的子节点。文本内容存储在此文本节点中,而不是存储在其父DIV元素中。

JQuery中的.text(),HTML DOM中的.innerHTML(),甚至.innerText()和.textContent()等方法的主要问题是它们都创建了 new 文本节点(即使已经存在)。更具体地说,上面列出的所有方法都是从删除所有 DOM子节点开始的,包括最终预先存在的文本节点(这也是由innerHTML,innerText和textContent的实现完成的)。这使得上下文元素(在您的情况下为DIV)为空,完全没有任何子项。然后,他们创建一个类型为text node的 new 子节点,为其分配新文本,并将其附加到context元素。 innerHTML还尝试解析输入HTML字符串并从中构造一个DOM片段。

我知道替换现有文本节点的最快方法如下:

var divs = $(".divs").get(),  
     len = divs.length;  
while(--len) {  
  divs[len].firstChild.data = "default";  
}

此方法不会创建新的子节点,而只是替换现有文本节点的文本。显然,此方法假定文本节点已存在。 为此,初始文档可以使用DIV内的任何非空文本进行初始化(并排除任何其他子元素)。

答案 4 :(得分:1)

如果您不需要转义html标记(即用<a>替换&lt;a&gt;),那么.html可能会更快。同样是的,它需要在用新内容替换它之前清空div。