1

私のアプリケーションには、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 を使用する必要がありますか?

4

2 に答える 2

4

さて、一連の改善により、このコードの実行にかかる時間を (Chrome 18 で一連の ~600 アイテムに対して) 3000 ミリ秒以上から 70 ミリ秒に短縮することができました。

最も劇的な改善は、jQuery の outerWidth() ステートメントの代わりに生の HTML 要素で offsetWidth を使用したことによってもたらされました。それだけで 50% 以上の時間を削減できました。

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

2 番目に劇的な変化は、私が行った 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');

3 番目に大きな改善点は、DOM をトラバースする回数が減ったことです。ループのたびに要素を選択する代わりに、事前にすべての要素を選択してから、ループ内のインデックスを参照しました。これにより、残りの改善点の大部分が占められました。

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

これが誰かを助けることを願っています!

于 2012-04-27T02:57:11.877 に答える
0

初心者の場合、これを$(this)で囲む必要はありません...何か(私がそうかもしれません)が見つからない場合を除いて、各$textfieldコンテキストで「this」を使用できるはずです...これにより、関数呼び出しと変数の作成。また、var宣言を関数の外に移動します...これにより、より多くのサイクルも節約できます。それが少しスピードアップするかどうか教えてください。

于 2012-04-26T23:18:59.867 に答える