为什么使用innerHTML比JQuery的append()函数更慢地将大量元素附加到DOM?

我有一个vanilla JavaScript函数来测试向DOM添加大量元素:

var start = new Date().getTime(); var blah; var div = document.getElementById("me"); for (i = 0; i < 5000; ++i) { div.innerHTML += "
" + i + "
";//Simply add to div. } var end = new Date().getTime(); var time = end - start; alert('Execution time: ' + time);

结果:

  Chrome IE10 ------ ----- Vanilla 39 130 (seconds) 

JQuery的:

 for (i = 0; i < 5000; ++i) { $("#me").append("
" + i + "
");//Now using append instead. }

结果

  Chrome IE10 ------ ----- Vanilla 39000 130,000 (milliseconds) JQuery 260 1300 (milliseconds) 

注意 :如果我使用$("#me")选择器或传入$(div)它似乎对性能没有任何影响

香草与AppendChild

 for (i = 0; i < 5000; ++i) { var el = document.createElement("div");//Now create an element and append it. el.innerHTML = i; div.appendChild(el); } 
  Chrome IE10 ------ ----- Vanilla 39000 130,000 (ms) JQuery 260 1300 (ms) AppendChild 30 240 (ms) 

令我惊讶的是,这是迄今为止最快,最高效的。 在Chrome上它需要大约30ms左右,在IE上大约需要240ms。

您可以在这里玩所有变化: 小提琴

我知道可能还有许多其他变种要测试,但是jQuery在幕后做什么才能使它的.append()比原生JS innerHTML +=快得多,为什么要创建一个新元素并将其追加得更快?

如果你做得对 ,你可以将你的“最佳”结果翻倍。

原生DOM方法总是比它们的jQuery替代方法更快。 但是, .innerHTML并不理想。

当你使用.innerHTML += ... ,会发生以下情况:

  1. 构建当前存在的整个DOM的HTML表示
  2. 将新字符串附加到其中
  3. 解析结果并从中创建一个全新的DOM树
  4. 把新东西放在旧东西的位置

本机方法的工作量明显减少;)

还应该注意, innerHTML += ... 完全核对DOM ,这意味着对旧元素的任何引用都会丢失,特别是不保留事件处理程序(除非你使用了内联事件处理程序,你不应该这样)

在幕后, jQuery使用的是文档片段 ,它比直接操作文档要好得多。 John Resig在2008年讨论了文档片段的优异性能 ,它可以为您提供有关jQuery正在做什么以及为什么做的可靠解释。

在我看来,如果你事先计算了你想要追加的所有内容,那么它会更有效率,然后追加 – 最小化所需的DOM操作。 例如:

 var toAppend = ""; for (i = 0; i < 5000; ++i) { toAppend += "
" + i + "
"; } div.append(toAppend)

如果您希望它们嵌套,您可以使其递归,或者提出其他解决方案。 无论哪种方式,我相信字符串操作总是比DOM操作更快