繁体   English   中英

执行者追加到现有DOM元素的数组

[英]Performant append to array of existing DOM elements

我有以下代码片段,该代码遍历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(''));

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

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

如果要处理已经属于DOM的多个元素,可以使用的一种策略是从DOM中临时删除那些节点的父节点,操纵这些元素,然后将父节点重新附加到原位置。

在下面的示例中,我在处理表的行之前先将其分离,然后将其重新连接到DOM。 那是2次重排,而不是n次重排。

 var data = [1, 2, 3, 4, 5, 6, 7]; populateCells(document.querySelector('table'), data); function populateCells(table, data) { var rows = table.rows, reAttachTable = temporarilyDetachEl(table); data.forEach(function (num, i) { rows[i].cells[0].innerHTML = num; }); reAttachTable(); } function temporarilyDetachEl(el) { var parent = el.parentNode, nextSibling = el.nextSibling; parent.removeChild(el); return function () { if (nextSibling) parent.insertBefore(el, nextSibling); else parent.appendChild(el); }; } 
 <table> <tr><td></td></tr> <tr><td></td></tr> <tr><td></td></tr> <tr><td></td></tr> <tr><td></td></tr> <tr><td></td></tr> <tr><td></td></tr> </table> 

您可以使用链接的文章中的一种技术来完全重建DOM元素集,然后清除现有的元素集并使用.append()新建元素集。 但是,鉴于您已经有了该集合,并且只想调整其项的子集,那么现有代码没有任何问题。

在谈论性能时,最好对代码进行概要分析,以免您猜测。

这是有关此示例的简单测试用例:

http://jsperf.com/most-performant-way-to-append-to-dom-elements

(以及相关的提琴来演示其视觉效果: http : //jsfiddle.net/f62ptjbf/

此测试比较了执行此操作的四种可能的方法:(决不涵盖所有解决方案)

  1. 附加“通过”作为文本节点(例如您的示例代码)
  2. 附加“通过”作为SPAN节点(示例略有变化)
  3. 构建一个DOM片段,以呈现节点并记录“通过”,然后将其作为HTML字符串中的单个附加操作添加到DOM
  4. 从DOM中删除selection元素,进行操作,然后重新添加到DOM中。

它表明[至少在我的Chrome浏览器副本中]最快的方法是在处理之前删除元素,然后在处理之后重新添加到DOM。 (#4)

这是另一项测试,显示[至少在我的Chrome浏览器中,]在SPAN元素中添加“通过”文本比在文本节点中添加文本更快。

http://jsperf.com/append-variations

基于这些发现,我可以建议对代码进行两项潜在的性能改进:

  1. 在操作之前,请删除selection内容中的DOM元素,然后在完成后重新添加。
  2. 附加带有文本“ passed”的SPAN ,而不是直接附加文本。

但是,如果元素具有共享的父级,则#1效果最佳。 性能将append操作的数量。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM