我对JS的表现有疑问。
比如说,我有下一个代码:
var divContainer = document.createElement("div"); divContainer.id="container";
var divHeader = document.createElement("div"); divHeader.id="header";
var divData = document.createElement("div"); divData.id="data";
var divFooter = document.createElement("div"); divFooter.id="footer";
divContainer.appendChild( divHeader );
divContainer.appendChild( divData );
divContainer.appendChild( divFooter );
document.getElementById("someElement").appendChild( divContainer );这段代码只为创建网格的其他函数创建shell,创建网格的过程非常复杂,并且经过多次验证,目前我使用两个方法填充网格,一个在数组变量中创建整个html,另一个创建元素并将它们附加到documentFragment中。
我的问题是,像我所理解的那样,在使用片段时,性能是否真的有了改善--它们管理内存中的元素,因此它们没有附加到文档中,因此不会触发DOM重新计算和其他一些讨厌的事情。但是,我创建变量的方式是,在我将容器附加到实际页面之前,它们不会附加到任何DOM元素。
因此,我想知道前面的代码是否比使用像这样包装它的文档片段具有更好的性能:
var fragment = document.createDocumentFragment();
var divContainer = document.createElement("div"); divContainer.id="container";
var divHeader = document.createElement("div"); divHeader.id="header";
var divData = document.createElement("div"); divData.id="data";
var divFooter = document.createElement("div"); divFooter.id="footer";
divContainer.appendChild( divHeader );
divContainer.appendChild( divData );
divContainer.appendChild( divFooter );
fragment.appendChild( divContainer )
document.getElementById("someElement").appendChild( fragment.cloneNode(true) );正如我已经说过的,这是一个关于性能的问题,我知道,作为一种最佳实践,建议使用片段,但是我不能从我的脑子里想出这样做只是在内存中创建一个新的对象而什么也不做,所以我假设在这种情况下丢弃这个片段是有效的。
希望一些js大师/上帝能在这里照亮希望之光,并帮助我们解决这个问题。
编辑:所以,我一直在寻找与这个问题相关的东西,而documentFragments似乎并不一定意味着更好的性能。
它只是一个“内存中”的节点容器。一个片段和一个<div>之间的区别是,该片段没有父片段,而且它永远不会在DOM上,只是在内存中,这意味着在片段上进行的操作更快,因为没有对DOM的操作。
W3C在documentFragments上的文档非常模糊,但切中要害,而且每个人最喜欢的浏览器都没有使用真正的片段,而是根据本MSDN文档创建了一个新文档,这意味着IE上的片段更慢。
所以,问题就来了,,如果我在变量中创建一个元素(例如,一个<div> ),但是不将它附加到DOM中,添加元素(div,table等)和东西,在完成所有工作之后,(循环、验证、元素样式),该元素被追加,它是否与片段相同?
考虑到IE使用“假”片段(至少在IE中使用这种方法) (使用div之类的元素,而不是片段)更好,我真的不关心IE,但我需要测试它(office的策略)。
另外,如果我在数组上创建了如下所示的所有html:
var arrHTML = ["<table>","<tr>", ....]; 然后做这个
document.getElementById("someElement").innerHTML = arrHTML.join(""); 它在IE上运行得更快,但其他主要浏览器( FF、Chrome、Safari和Opera )在使用容器并附加它(片段或div)时表现得更好。
所有这一切都是因为创建所有元素的过程非常快,大约8-10秒就可以创建多达2万行,24列,这是很多元素/标签,但浏览器似乎冻结了几秒钟,当它们都附加在一起,如果我试着一个接一个地追加,那就太糟了。
再次感谢各位,这真的很有趣和有趣。
发布于 2016-02-06 15:16:21
当文档片段用于在多位置中插入一组元素时,它的速度要快得多。这里的大多数答案都指出了它的无用之处,但这是为了证明它的力量。
让我们举个例子。
假设我们需要在10个元素中添加20个div和类容器。
没有:
var elements = [];
for(var i=20; i--;) elements.push(document.createElement("div"));
var e = document.getElementsByClassName("container");
for(var i=e.length; i--;) {
for(var j=20; j--;) e[i].appendChild(elements[j].cloneNode(true));
}通过以下方式:
var frag = document.createDocumentFragment();
for(var i=20; i--;) frag.appendChild(document.createElement("div"));
var e = document.getElementsByClassName("container");
for(var i=e.length; i--;) e[i].appendChild(frag.cloneNode(true));对我来说,在Chrome 48上使用文档片段的速度要快16倍。
JsPerf测试
发布于 2013-01-07 21:00:24
通常,您需要使用片段来避免重绘(重新绘制页面)。一个很好的例子是,如果您正在循环一些东西,并在循环中附加,但是,我认为现代浏览器已经为此优化了。
我设置了一个jsPerf来演示何时使用片段这里的一个很好的例子。在Chrome中,您会注意到几乎没有什么不同(我猜想,现代优化正在起作用),但是,在IE7中,没有片段的.08操作系统/秒是3.28个ops/秒。
因此,如果您正在遍历一个大型数据集,并附加了许多元素,则可以使用一个片段来代替它,这样您就只有一个重流。如果您只是向dom添加了几次,或者您只是在访问现代浏览器,那么这是不必要的。
发布于 2013-01-07 20:11:31
我编写了一个jspref来测试这一点,看起来节点片段的速度要快2.34 %。
http://jsperf.com/document-fragment-test-peluchetti
https://stackoverflow.com/questions/14203196
复制相似问题