在处理大型集合

时间:2015-12-18 14:20:46

标签: javascript jquery css performance

我使用jQuery故意从潜在的大型html表中的元素中删除css类。请参阅下文,了解我为何会这样做。

目前我这样做:

var tableElements = $("#TreeListElemente").find("*").addBack();
tableElements.removeClass("dxtl dxtl__B2 dxtl__B0 dxtlSelectionCell dxtlHeader dxtl__B3 dxtlControl dx-wrap dxtl__IM dxeHyperlink");

桌子有时很大,有很多元素。我想加快页面加载/ DOM操作。

IE的内置Javascript探查器告诉我,特别是.addBack()很慢。它似乎做了某种排序,这对我的用例来说是完全没有必要的。我可以摆脱它吗?除了addBack()?还有其他方法可以包含所选元素本身吗?

IE javascript profiler tree view

IE javascript profiler:大约60000个元素的集合的执行时间。包容性时间在第三栏

是否有另一种更有效的方法从大量元素中删除类,选择元素,本身和所有子元素?

注意:为什么我这样做:我使用DevXpress TreeList组件,它附带了它自己的样式。没有简单的方法在服务器端“unstyle it”,因此我选择做客户端,就像上面演示的那样。最后,我选择TreeList,所有子元素,并从中删除相关的css类。

更新/解决方案1 ​​

我已经成功实施了FrédéricHamidi提出的解决方案,并取得了相当大的进步:

IE javascript profiler tree view

IE javascript profiler:使用Frederic的提案,对大约60000个元素的集合执行时间。包容性时间在第三栏

addBack()操作所需的时间刚刚消失,只剩下其他的东西了。这意味着整体提高了4倍以上。耶!

更新/解决方案2

我还实施了A. Wolff提出的解决方案,并得到了一些改进:

IE javascript profiler tree view

IE javascript profiler:使用A. Wolff提议的大约60000个元素的集合的执行时间。包容性时间在第三栏

find()操作所需的时间消失了,只剩下其他的东西了。这意味着我的机器略微改进了大约10毫秒。太酷了!

这是我现在使用的解决方案:

$("#TreeListElemente, #TreeListElemente [class]").removeClass("dxtl dxtl__B2 dxtl__B0 dxtlSelectionCell dxtlHeader dxtl__B3 dxtlControl dx-wrap dxtl__IM dxeHyperlink");

3 个答案:

答案 0 :(得分:4)

addBack()执行排序以将匹配的元素按文档顺序排列。简单的替代方法add()完全相同,因此无法解决您的问题。

但是,该文档足以提供解决方案:

  

使用定义良好的顺序创建一个jQuery对象   如果没有排序开销,请使用$(array_of_DOM_elements)签名。

因此,为了避免这种开销,你可以写:

var ancestor = $("#TreeListElemente"),
    tableElements = $(ancestor.find("*").get().concat(ancestor[0]));

get()concat()最终会在引擎盖下构建两个阵列,因此会影响性能。最终结果可能比您当前的方法更快,具体取决于您匹配的元素数量。

答案 1 :(得分:3)

选择ID为TreeListElemente的元素及其所有后代的相关选择器为:

"#TreeListElemente, #TreeListElemente *"

现在你可以过滤出具有类的后代:

"#TreeListElemente, #TreeListElemente [class]"

所以它会给:

$("#TreeListElemente, #TreeListElemente [class]").removeClass("dxtl dxtl__B2 dxtl__B0 dxtlSelectionCell dxtlHeader dxtl__B3 dxtlControl dx-wrap dxtl__IM dxeHyperlink");

答案 2 :(得分:0)

这是一个想法:

function deClassify(jq, classes) {
  var remove = classes.join(' ');
  jq.find('.' + classes.join(',.')).removeClass(remove);
  jq.removeClass(remove);
}

deClassify($('.keepme'), ['remove', 'remove2', 'remove3']);
.remove, .remove2, .remove3 {
  color: red;
}
.keepme, .keepme2 {
  font-weight: bold;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="keepme remove remove2">
  <div class="keepme2 remove remove3">x</div>
</div>

这可以避免“选择”不匹配的元素,减少负载,当然也不会涉及额外的排序......