私はオブジェクトの配列に対して非常に頻繁に反復を行っており、jQuery.each() を使用しています。ただし、速度とメモリの問題があり、プロファイラーによると最も呼び出されるメソッドの 1 つは jQuery.each() です。そのパフォーマンスについて巷ではどんな言葉が聞かれますか? 単純な for ループに切り替える必要がありますか? もちろん、自分のコードでも多くの問題を修正しています。
5 に答える
この記事(#3)はいくつかのパフォーマンステストを実行し、jQuery.each関数がネイティブのjavascriptforループの約10倍遅いことを発見しました。
jQueryのパフォーマンスを即座に向上させる10の方法から-3。Firebugを使用する代わりにForを使用する
と、 2つの関数のそれぞれの実行にかかる時間を測定できます。var array = new Array (); for (var i=0; i<10000; i++) { array[i] = 0; } console.time('native'); var l = array.length; for (var i=0;i<l; i++) { array[i] = i; } console.timeEnd('native'); console.time('jquery'); $.each (array, function (i) { array[i] = i; }); console.timeEnd('jquery');
上記の結果は、ネイティブコードの場合は2ミリ秒、jQueryの「each」メソッドの場合は26ミリ秒です。ローカルマシンでテストし、実際には何も実行していない場合(単なる配列の入力操作)、jQueryの各関数はJSネイティブの「for」ループの10倍以上の時間がかかります。これは、CSS属性の設定やその他のDOM操作操作など、より複雑なものを処理する場合に確実に増加します。
jQueryのそれぞれのソースコードは次のとおりです(John ResigとMITライセンスに感謝します)。
each: function( object, callback, args ) {
var name, i = 0, length = object.length;
if ( args ) {
if ( length === undefined ) {
for ( name in object )
if ( callback.apply( object[ name ], args ) === false )
break;
} else
for ( ; i < length; )
if ( callback.apply( object[ i++ ], args ) === false )
break;
// A special, fast, case for the most common use of each
} else {
if ( length === undefined ) {
for ( name in object )
if ( callback.call( object[ name ], name, object[ name ] ) === false )
break;
} else
for ( var value = object[0];
i < length && callback.call( value, i, value ) !== false; value = object[++i] ){}
}
return object;
}
トレースして確認できるように、ほとんどの場合、基本的なforループを使用しており、オーバーヘッドは実際にはコールバック自体だけです。パフォーマンスに違いはありません。
編集:これは、セレクターのオーバーヘッドがすでに発生しており、入力された配列が与えられていることを認識していますobject
。
この方法では、速度が劇的に向上します。
var elements = $('.myLinks').get(), element = null;
for (var i = 0, length = elements.length; i < length; i++) {
element = elements[i];
element.title = "My New Title!";
element.style.color = "red";
}
キャッシングによってパフォーマンスも向上します。
function MyLinkCache() {
var internalCache = $('.myLinks').get();
this.getCache = function() {
return internalCache;
}
this.rebuild = function() {
internalCache = $('.myLinks').get();
}
}
使用中で:
var myLinks = new MyLinkCache();
function addMyLink() {
// Add a new link.
myLinks.rebuild();
}
function processMyLinks() {
var elements = myLinks.getCache(), element = null;
for (var i = 0, length = elements.length; i < length; i++) {
element = elements[i];
element.title = "My New Title!";
element.style.color = "red";
}
}
jquery を最大限に活用する方法の 1 つは、何かを取得する必要があるたびに DOM を再走査するのではなく、返された結果の配列を変数に格納することです。
してはいけないことの例:
$('.myLinks').each(function(){
// your code here
});
$('.myLinks').each(function(){
// some more code here
});
ベター プラクティス:
var myLinks = $('.myLinks');
myLinks.each(function(){
// your code here
});
myLinks.each(function(){
// some more code here
});
通常、ネイティブ機能を使用すると、JQuery.each() メソッドなどの抽象化よりも高速になります。ただし、JQuery.each() メソッドの方が使いやすく、コーディングが少なくて済みます。
正直なところ、コンテキストがなければ、どちらも正しい選択でも間違った選択でもありません。私は、それが良い/読みやすい/きれいなコードであると仮定して、最初に簡単なコードを書くべきだという意見です。あなたが説明しているような状況に陥った場合、顕著な遅延がある場合は、ボトルネックがどこにあるかを見つけて、より高速なコードを作成する必要があります。
これらのシナリオで JQuery.each() メソッドを置き換えると役立つ場合がありますが、コードを確認していない場合は、JQuery メソッドとは関係のないボトルネックがある可能性があります。