Javascript Performant附加到现有DOM元素的数组

Javascript Performant附加到现有DOM元素的数组,javascript,jquery,performance,dom,Javascript,Jquery,Performance,Dom,我有下面的一段代码,它在DOM对象数组上循环,运行测试,并在返回true时向节点追加一些文本 $.each( selections, function ( i, e ) { var test = some_test(e); if(test) { $(e).append('passed'); } }); 虽然这段代码工作得很好,但在一个大型集合上,它显然将执行许多DOM的附加操作。本文演示了附加到DOM的性能如何更高: var arr = reallyLon

我有下面的一段代码,它在DOM对象数组上循环,运行测试,并在返回true时向节点追加一些文本

$.each( selections, function ( i, e ) {
    var test = some_test(e);
    if(test) {
       $(e).append('passed');
    }
});
虽然这段代码工作得很好,但在一个大型集合上,它显然将执行许多DOM的附加操作。本文演示了附加到DOM的性能如何更高:

var arr = reallyLongArray;
var textToInsert = [];
var i = 0;
$.each(arr, function(count, item) {
    textToInsert[i++]  = '<tr><td name="pieTD">';
    textToInsert[i++] = item;
    textToInsert[i++] = '</td></tr>';
});
$('table').append(textToInsert.join(''));
var arr=reallyLongArray;
var textToInsert=[];
var i=0;
$。每个(arr,功能(计数,项目){
textToInsert[i++]='';
textToInsert[i++]=项;
textToInsert[i++]='';
});
$('table').append(textToInsert.join('');

我的问题是,在不必对每个元素调用
.append
的情况下,对一组现有DOM元素进行更改的最有效的方法是什么?上面的示例演示了新元素的创建。这是唯一的方法吗?

您可以使用链接文章中的一种技术完全重建DOM元素集,然后清除现有的元素集并添加新的元素集。但是,考虑到您已经拥有了集合,并且只想调整它的一个子集,您现有的代码没有问题。

导致实时DOM操作变慢的主要原因是它导致大多数操作的DOM回流。因此,您应该通过减少活动DOM操作的数量来努力减少DOM回流的数量

如果要操纵已经是DOM一部分的多个元素,可以使用的一种策略是暂时从DOM中删除这些节点的父节点,操纵这些元素,然后将父节点重新连接到它原来所在的位置

在下面的示例中,我在操作表的行之前分离表,然后将其重新附加到DOM。这是2次回流,而不是n次回流

var数据=[1,2,3,4,5,6,7];
填充单元格(document.querySelector('table'),数据);
函数populateCells(表、数据){
var rows=table.rows,
再附着=暂时分离(表);
data.forEach(函数(num,i){
行[i]。单元格[0]。innerHTML=num;
});
可重新连接();
}
功能暂时分离el(el){
var parent=el.parentNode,
nextSibling=el.nextSibling;
父母。远程儿童(el);
返回函数(){
if(nextSibling)parent.insertBefore(el,nextSibling);
else父项、子项(el);
};
}

在谈论性能时,最好对代码进行概要分析,这样您就不必猜测了

下面是一个关于此示例的简单测试用例:

(和相关的提琴来演示这张照片的视觉效果:)

该测试比较了四种可能的方法:(绝不包括所有的解决方案)

  • 附加“passed”作为文本节点(如示例代码)
  • 将“passed”附加为
    SPAN
    节点(与示例略有不同)
  • 构建一个DOM片段,用于呈现节点并记录“已传递”,然后将其作为HTML字符串的单个附加操作添加到DOM中
  • 从DOM中删除
    selection
    元素,对其进行操作,然后重新添加到DOM中
  • 它表明[至少在我的Chrome浏览器副本中]最快的方法是在处理之前删除元素,然后在处理之后重新添加到DOM。(#4)

    下面是另一个测试,它显示[至少在我的Chrome副本中]在
    SPAN
    元素中添加文本“通过”比添加文本节点更快

    基于这些发现,我可以向您的代码推荐两种潜在的性能改进:

  • 在操作DOM元素之前,先删除
    选择中的DOM元素,然后在操作完成后重新添加
  • SPAN
    与文本“passed”一起追加,而不是直接追加文本

  • 但是,如果元素具有共享的父元素,则#1的效果最好。性能取决于
    append
    操作的数量。

    我不理解这个问题<代码>追加
    添加新元素。您不应该使用
    append
    对现有元素进行更改一般做法是尽可能长时间推迟对DOM进行更改。对DOM的每次更改都会单独重新绘制。这既适用于添加新元素,也适用于对现有元素进行更改,因为您阅读的文章已超过5年。浏览器引擎已经开始运行。“远不止”变成了“有时多一点”。在您的情况下,正如您所注意到的,特定的“优化”甚至不适用。用你已经拥有的,它是最可读的。