为什么使用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 += ...
,会发生以下情况:
- 构建当前存在的整个DOM的HTML表示
- 将新字符串附加到其中
- 解析结果并从中创建一个全新的DOM树
- 把新东西放在旧东西的位置
本机方法的工作量明显减少;)
还应该注意, innerHTML += ...
完全核对DOM ,这意味着对旧元素的任何引用都会丢失,特别是不保留事件处理程序(除非你使用了内联事件处理程序,你不应该这样)
在幕后, jQuery使用的是文档片段 ,它比直接操作文档要好得多。 John Resig在2008年讨论了文档片段的优异性能 ,它可以为您提供有关jQuery正在做什么以及为什么做的可靠解释。
在我看来,如果你事先计算了你想要追加的所有内容,那么它会更有效率,然后追加 – 最小化所需的DOM操作。 例如:
var toAppend = ""; for (i = 0; i < 5000; ++i) { toAppend += "" + i + ""; } div.append(toAppend)
如果您希望它们嵌套,您可以使其递归,或者提出其他解决方案。 无论哪种方式,我相信字符串操作总是比DOM操作更快