9つの方法でjQueryコードの詳細を最適化

8249 ワード

ペアセレクタ
jQueryでは、複数のセレクタを使用して、同じページ要素を選択できます.各セレクタのパフォーマンスは異なり、パフォーマンスの違いを理解する必要があります.
1、最も速いセレクタ:idセレクタと要素ラベルセレクタ
たとえば、次の文のパフォーマンスが最適です.

$('#id')
$('form')
$('input')

これらのセレクタに遭遇すると、jQuery内部でブラウザのオリジナルメソッド(getElementById()など)が自動的に呼び出されるため、実行速度が速くなります.
2、遅いセレクタ:classセレクタ
$('.className')のパフォーマンスは、ブラウザによって異なります.Firefox、Safari、Chrome、Operaブラウザは、いずれもオリジナルメソッドgetElementByClassName()があるので、速度は遅くありません.しかし、IE 5-IE 8はこの方法を導入していないため、このセレクタはIEでかなり遅い
3、最も遅いセレクタ:擬似クラスセレクタと属性セレクタ
ページ内のすべての非表示要素を検索するには、擬似クラスセレクタを使用します.

$(':hidden')

プロパティ・セレクタの例は、次のとおりです.

$('[attribute=value]')

ブラウザには元の方法がないため、この2つの文が最も遅いです.しかし、一部のブラウザの新しいバージョンでは、querySelector()とquerySelectorAll()メソッドが追加されているため、このようなセレクタのパフォーマンスが大幅に向上します.
親子関係の理解
次の6つのセレクタは、親要素から子要素を選択します.

$('.child', $parent)
$parent.find('.child')
$parent.children('.child')
$('#parent > .child')
$('#parent .child')
$('.child', $('#parent'))

1、次の文の意味は、DOMオブジェクトを指定し、その中からサブ要素を選択することです.jQueryはこの文を自動的に$に変換します.parent.find('child')は、一定のパフォーマンス損失をもたらします.最も速い形式より5%-10%遅いです

$('.child', $parent)

2、これは一番速い文です.find()メソッドはブラウザのオリジナルメソッド(getElementById,getElementByName,getElementByTagNameなど)を呼び出すので、速度が速い

$parent.find('.child')

3、この文はjQueryの内部にあり、$が使用されます.Sibling()とjavascriptのnextSibling()メソッドは、ノードを1つずつ巡回します.最も速い形より約50%遅いです

$parent.children('.child')

4、jQuery内部はSizzleエンジンを使用し、各種セレクタを処理する.Sizzleエンジンの選択順序は右から左なので、この文は先に選択します.childは、親要素parentをさらにフィルタリングし、最も速い形式より約70%遅い

$('#parent > .child')

5、この文は前の文と同じです.しかし、前のサブエレメントは直接のサブエレメントのみを選択し、これはマルチレベルのサブエレメントを選択できるので、その速度はもっと遅く、最も速い形式より77%遅いかもしれません.

$('#parent .child')

6、jQuery内部ではこの文を$('#parent')に変換します.find('.child')は、最も速い形式より23%遅い

$('.child', $('#parent'))

だから、最適な選択は$parentです.find('.child').また,$parentは往々にして前の操作で生成され,jQueryはキャッシュされるため,実行速度がさらに速くなる.
jQueryを過度に使用しない
jQueryの速度がいくら速くても、オリジナルのjavascriptメソッドとは比べものになりません.原生的な方法で使える場合は、jQueryは避けましょう.
最も簡単なセレクタを例にとるとdocument.getElementById(「foo」)は$(「#foo」)より10倍以上速い
もう1つの例を見て、a要素にクリックイベントを処理する関数をバインドします.

  $('a').click(function(){

    alert($(this).attr('id'));

  });

このコードの意味は、a要素をクリックすると、その要素のid属性がポップアップされます.この属性を取得するには、jQueryを2回連続して呼び出す必要があります.1回目は$(this)、2回目はattr('id')です.
実際、このような処理は全く必要ありません.より正確な書き方はjavascriptのオリジナルメソッドを直接採用し、thisを呼び出すことです.id:

  $('a').click(function(){

    alert(this.id);

  });

テストによるとidの速度比$(this).attr('id')は20倍以上速くなりました
キャッシュを作成
Web要素を選択すると、コストがかかります.したがって、セレクタを使用する回数は少ないほうがよいし、選択した結果をできるだけキャッシュし、後で繰り返し使用するのに便利である.
例えば、次のような書き方は悪い書き方です.

  jQuery('#top').find('p.classA');

  jQuery('#top').find('p.classB');

もっと良い書き方は:

  var cached = jQuery('#top');

  cached.find('p.classA');

  cached.find('p.classB');

テストによると、キャッシュはキャッシュしないより2~3倍速い
jQueryの大きな特徴は、チェーン式の書き方を許可することです

$('div').find('h3').eq(2).html('Hello');

チェーン書き方を採用する場合、jQueryは各ステップの結果を自動的にキャッシュするので、非チェーン書き方よりも速い.テストによると、チェーン書き方は(キャッシュを使用しない)非チェーン書き方より約25%速い.
イベントの委任
JAvascriptのイベントモデルは、「バブル」モードを採用しています.つまり、サブエレメントのイベントは段階的に「バブル」し、親エレメントのイベントになります.
これにより,イベントのバインドを大幅に簡素化できる.例えば、100個の格子(td要素)が入ったテーブル(table要素)があります.現在、各格子にクリックイベント(click)をバインドするように要求されていますが、次のコマンドを100回実行する必要がありますか?

  $("td").on("click", function(){

    $(this).toggleClass("click");

  });

答えは必要ありません.私たちはこのイベントをtable要素の上にバインドすればいいです.td要素がクリックイベントを発生した後、このイベントは親要素tableの上に「泡が立つ」ので、傍受されます.
したがって、このイベントは親要素を100回バインドする必要がなく、親要素を1回バインドするだけで済むため、パフォーマンスが大幅に向上します.これをイベントの「委任処理」と呼びます.つまり、サブエレメントの「委任」親エレメントがこのイベントを処理します.

  $("table").on("click", "td", function(){

    $(this).toggleClass("click");

  });

より良い方法は、documentオブジェクトにイベントをバインドすることです.

  $(document).on("click", "td", function(){

    $(this).toggleClass("click");

  });

イベントのバインドを解除する場合はoff()メソッドを使用します.

$(document).off("click", "td");

少ない変更DOM
1.DOMの構造変更はコストがかかるので、頻繁に使用することはない.append()、.InsertBefore()と.insetafter()という方法
複数の要素を挿入する場合は、まずそれらを結合してから、一度に挿入します.テストによると、マージ挿入はマージしない挿入よりも10倍近く速くなりました.
2.一つのDOM元素を大量に処理する場合は、先に用いるべきである.detach()メソッドは、この要素をDOMから取り出し、処理が完了したら、ドキュメントに再挿入します.テストに基づいて、使用します.detach()メソッドは使用しない場合より60%速くなりました
3、DOM要素にデータを保存する場合は、次のように書かないでください.

  var elem = $('#elem');

  elem.data(key,value);

書く

  var elem = $('#elem');

  $.data(elem[0],key,value);

テストによると、後者の書き方は前の書き方より10倍近く速くなった.なぜならData()メソッドは、jQuery関数のprototypeオブジェクト上に定義、$である.Data()メソッドはjQuery関数上を定義しており,呼び出す際に複雑なjQueryオブジェクトから呼び出さないため,より高速である.
4、htmlコードを挿入するとき、ブラウザのオリジナルのinnterHTML()メソッドはjQueryオブジェクトのhtml()よりも速い
jQueryオブジェクトの生成を最小限に抑える
セレクタ($('#id')など)を使用するたびに、jQueryオブジェクトが生成されます.jQueryオブジェクトは膨大なオブジェクトであり、多くの属性と方法があり、多くのリソースを占有します.したがって、jQueryオブジェクトの生成を最小限に抑える
たとえば、多くのjQueryメソッドには、jQueryオブジェクトで使用されるバージョンと、jQuery関数で使用されるバージョンの2つのバージョンがあります.次の2つの例は,いずれも1つの要素のテキストを取り出し,text()メソッドを用いる.
jQueryオブジェクトのバージョンを使用することもできます.

  var $text = $("#text");

  var $ts = $text.text();

jQuery関数のバージョンも使用できます.

  var $text = $("#text");

  var $ts = $.text($text);

後者のjQuery関数のバージョンはjQueryオブジェクトによって操作されないため、相対的にオーバーヘッドが小さく、速度が速い
役割ドメインチェーンが最も短い方法を選択
厳密に言えば、この原則はjQueryだけでなく、すべてのJavascriptプログラミングに適用されます.
Javascriptの変数はチェーン型の役割ドメインを採用していることを知っています.変数を読み込むときは、まず現在の役割ドメインで変数を探し、見つからない場合は前のレイヤの役割ドメインで変数を探します.このような設計により、ローカル変数の読み取りがグローバル変数の読み取りよりもずっと速くなる
次の2つのコードを見てください.最初のコードはグローバル変数を読み込むことです.

  var a = 0;

  function x(){

    a += 1;

  }

2番目のセグメントコードは、ローカル変数を読み込みます.

  function y(){

    var a = 0;

    a += 1;

  }

2段目のコードが変数aを読み取る場合は、上の層の役割ドメインに行かなくてもよいので、1段目のコードより5、6倍速くなります
同様に、オブジェクトメソッドを呼び出す場合、closureモードはprototypeモードよりも速くなります.
prototypeモード:

  var X = function(name){ this.name = name; }

  X.prototype.get_name = function() { return this.name; };

closureモード:

  var Y = function(name) {

    var y = { name: name };

    return { 'get_name': function() { return y.name; } };

  };

同じくget_name()メソッド、closureモードの方が速い
Pub/subモードでイベントを管理する
イベントが発生した後、複数の操作を連続的に実行する場合は、次のように書かないほうがいいです.

  function doSomthing{

    doSomethingElse();

    doOneMoreThing();

  }

では、イベントトリガの形式を変更します.

  function doSomething{

    $.trigger("DO_SOMETHING_DONE");

  }

  $(document).on("DO_SOMETHING_DONE", function(){

    doSomethingElse(); 

  });

deferredオブジェクトの使用も考えられます

  function doSomething(){
    var dfd = new $.Deferred();
    //Do something async, then... 
    //dfd.resolve();
    return dfd.promise();
  }
  function doSomethingElse(){
    $.when(doSomething()).then(//The next thing);
  }

jQueryコードの最適化方法については、次のリンクをクリックしてください.