34

私はオブジェクトの配列に対して非常に頻繁に反復を行っており、jQuery.each() を使用しています。ただし、速度とメモリの問題があり、プロファイラーによると最も呼び出されるメソッドの 1 つは jQuery.each() です。そのパフォーマンスについて巷ではどんな言葉が聞かれますか? 単純な for ループに切り替える必要がありますか? もちろん、自分のコードでも多くの問題を修正しています。

4

5 に答える 5

29

この記事(#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操作操作など、より複雑なものを処理する場合に確実に増加します。

于 2009-12-10T20:12:53.667 に答える
15

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

于 2009-12-10T20:13:55.193 に答える
8

この方法では、速度が劇的に向上します。

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";
    }
}
于 2009-12-10T20:12:09.563 に答える
7

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
});
于 2009-12-10T20:08:19.367 に答える
6

通常、ネイティブ機能を使用すると、JQuery.each() メソッドなどの抽象化よりも高速になります。ただし、JQuery.each() メソッドの方が使いやすく、コーディングが少なくて済みます。

正直なところ、コンテキストがなければ、どちらも正しい選択でも間違った選択でもありません。私は、それが良い/読みやすい/きれいなコードであると仮定して、最初に簡単なコードを書くべきだという意見です。あなたが説明しているような状況に陥った場合、顕著な遅延がある場合は、ボトルネックがどこにあるかを見つけて、より高速なコードを作成する必要があります。

これらのシナリオで JQuery.each() メソッドを置き換えると役立つ場合がありますが、コードを確認していない場合は、JQuery メソッドとは関係のないボトルネックがある可能性があります。

于 2009-12-10T21:22:52.723 に答える