繁体   English   中英

加快jQuery对列表的操作

[英]Speed up jQuery manipulation of a list

我的应用程序有很长的对象列表,其宽度需要通过jQuery进行修改。 目前我正在使用这样的代码:

$('#my_list div.text_field').each(function() {
  // Cache objects we're going to use multiple times.
  var $textField = $(this);
  var $listContents = $textField.closest('div.list_contents');

  // Find widths.
  var contentsWidth = $listContents.outerWidth();
  var avatarsWidth = $listContents.find('div.avatars').outerWidth();
  var tagsWidth = $listContents.find('div.tags').outerWidth();
  var textLeft = $textField.position().left;

  // Update the width.
  var newTextWidth = contentsWidth - textLeft - avatarsWidth - tagsWidth;
  $textField.css({ width: newTextWidth });
});

但是,当需要操作数百个对象时,需要一段时间(> 1秒)。 知道如何让它更快吗? 我应该完全避免使用jQuery并使用原生JS吗?

好的,通过一系列改进,我能够缩短运行此代码所花费的时间(在一系列约600个项目上的Chrome 18上)从3000毫秒减少到70毫秒。

最大的改进来自于在原始HTML元素上使用offsetWidth而不是jQuery的outerWidth()语句。 仅在50%的时间内,这一切都被削减了:

avatarsWidth = $listContents.find('div.avatars')[0].offsetWidth;

第二个最大的变化来自减少我所做的DOM修改的数量。 在上面的代码中,我循环遍历元素,计算它们的宽度,然后立即将这些宽度应用于DOM。 在我改进的代码中,我仍然循环计算宽度,但是然后我存储这些宽度,从DOM中分离元素,应用存储的宽度,并重新附加它们。 感谢@muffel这个想法。 这削减了超过总时间的30%:

$('#my_list div.text_field').each(function() {
  var $textField = $(this);
  // ...
  var newTextWidth = contentsWidth - textLeft - avatarsWidth - tagsWidth;
  $textField.attr('data-width', newTextWidth);
});

$('#my_list')
  .detach()
  .find('div.text_field')
    .each(function() {
      $(this).css({ width: $(this).attr('data-width') });
    })
    .end()
  .appendTo('#container');

第三大改进来自减少遍历DOM的次数。 我不是每次都通过循环选择元素,而是先选择它们,然后引用循环内的索引。 这构成了剩余改进的大部分:

var $avatars = $('#my_list .avatars');
// ...
$('#my_list div.text_field').each(function(i) {
  // ...
  avatarsWidth = $avatars.eq(i).offsetWidth;
  // ...
});

希望这有助于某人!

对于初学者你不应该用$(this)来包装它...除非我遗漏了某些东西(我可能是),你应该能够在每个$ textfield上下文中使用“this”...这样可以节省你的时间函数调用和var创建。 同时将var声明移出函数...这也将节省更多周期。 如果这样可以加快速度,请告诉我。

暂无
暂无

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

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