ホームページ >ウェブフロントエンド >jsチュートリアル >Javascriptの実行効率の問題を探る_基礎知識

Javascriptの実行効率の問題を探る_基礎知識

WBOY
WBOYオリジナル
2016-05-16 16:31:251388ブラウズ

JavaScript は非常に柔軟な言語であり、さまざまなスタイルのコードを自由に記述できます。開発プロセスでは、必然的に実行効率に違いが生じます。 、一般的で回避しやすい問題を整理します

JavaScript 自体の実行効率
Javascript のスコープチェーン、クロージャ、プロトタイプ継承、eval などの機能は、さまざまな魔法の機能を提供するだけでなく、不注意に使用するとさまざまな効率上の問題を引き起こします。

1. グローバルインポート
コーディング プロセスでは、多かれ少なかれいくつかのグローバル変数 (ウィンドウ、ドキュメント、カスタム グローバル変数など) を使用します。JavaScript スコープ チェーンを理解している人なら、ローカル スコープ内のグローバル変数にアクセスするにはスコープ全体が必要であることを知っています。チェーンは最上位スコープまで階層ごとにトラバースされ、ローカル変数へのアクセス効率がより高速かつ高くなるため、一部のグローバル オブジェクトがローカル スコープで頻繁に使用される場合、それらをローカル スコープにインポートできます。例:

コードをコピーします コードは次のとおりです:

//1. モジュールをパラメータとして渡します
(関数(ウィンドウ,$){
var xxx = window.xxx
$("#xxx1").xxx(); $("#xxx2").xxx(); })(ウィンドウ,jQuery);
//2. ローカル変数に一時的に保存します
function(){
var doc = ドキュメント; var グローバル = window.global
}




2. eval と eval に似た問題
eval が文字列を JS コードとして処理できることは誰もが知っています。eval を使用して実行されたコードは、eval を使用しないコードよりも 100 倍以上遅いと言われています (具体的な効率をテストしたことはありません。興味のある学生はテストしてみてください)。

JavaScript コードは、実行前に同様の「プリコンパイル」操作を実行します。まず、現在の実行環境でアクティブ オブジェクトを作成し、var で宣言された変数をアクティブ オブジェクトの属性として設定しますが、この時点では、変数の代入値はすべて未定義であり、function で定義された関数もアクティブ オブジェクトのプロパティとして追加され、その値は関数の定義とまったく同じになります。ただし、「eval」を使用すると、「eval」内のコード (実際には文字列) は事前にコンテキストを認識できず、事前に解析および最適化することができません。つまり、プリコンパイルされた操作を実行できません。したがって、パフォーマンスも大幅に低下します
実際、最近では eval を使用する人はほとんどいません。ここで説明したいのは、eval に似た 2 つのシナリオ (new Function{}、setTimeout、setInterver) です。

コードをコピーします

コードは次のとおりです: setTimtout("alert(1)",1000); setInterver("alert(1)",1000); (new Function("alert(1)"))();

上記の種類のコードは実行効率が比較的低いため、匿名メソッドまたはメソッド参照を setTimeout メソッドに直接渡すことをお勧めします


3. クロージャ終了後、参照されなくなった変数を解放します

コードをコピーします

アラート(a.name); }
応答を返す
})()



上記のコードの変数 f の戻り値は、すぐに実行される関数で構成されるクロージャで返されるメソッド res です。この変数は、このクロージャ内のすべての変数 (a、b、c など) への参照を保持します。これら 2 つの変数は常にメモリ空間に存在し、特に dom 要素への参照は大量のメモリを消費しますが、res では変数の値のみを使用するため、クロージャが戻る前に Release できます。その他の変数





コードをコピー
コードは次のとおりです:


var f = (function(){
var a = {名前:"var3"}; var b = ["var1","var2"]; var c = document.getElementByTagName("li"); //****その他の変数
//***一部の操作
// クロージャが
を返す前に、使用されなくなった変数を解放します。 b = c = null; var res = function(){
アラート(a.name); }
応答を返す
})()




Js が dom を操作する効率
Web 開発のプロセスでは、フロントエンドの実行効率のボトルネックになることがよくあります。DOM 操作は非常にパフォーマンスを消費します。DOM 操作中のパフォーマンスをできるだけ節約するにはどうすればよいでしょうか。

1. リフローを削減します リフローとは何ですか? DOM 要素のプロパティ (色など) が変更されると、ブラウザは対応する要素を再描画するようにレンダリングに通知します。このプロセスは再描画と呼ばれます。

変更に要素のレイアウト (幅など) が含まれる場合、ブラウザーは元の属性を破棄し、再計算して結果をレンダリングに渡し、ページ要素を再描画します。このプロセスはリフローと呼ばれます。


リフローを軽減する方法
まずドキュメントから要素を削除し、変更が完了したら要素を元の位置に戻します (要素とそのサブ要素に対して多数のリフロー操作が実行されると、方法 1 と 2 の効果が低下します)。より明白です)

要素の表示を「なし」に設定し、修正が完了したら元の値に戻します

複数のスタイル属性を変更する場合は、スタイル属性を複数回変更するのではなく、クラス クラスを定義します (特定の学生に推奨)

ページに多数の要素を追加する場合は documentFragment

を使用します 例:




コードをコピーします

コードは次のとおりです: for(var i=0;i var child = docuemnt.createElement("li");
child.innerHtml = "子";
document.getElementById("親").appendChild(子);

}

コードが要素のステータス情報に複数回アクセスする必要がある場合、ステータスが変更されない場合は一時的に変数に格納できます。これにより、DOM への複数回のアクセスによって発生するメモリ オーバーヘッドを回避できます。 >

DOM 要素を検索するときは、ページ要素の広い領域を走査しないようにするか、正確なセレクターを使用するか、コンテキストを指定して検索範囲を狭めるようにしてください。jquery を例に挙げます。

$("[name*='_fix']") などのあいまい一致セレクターを使用せず、id や徐々に範囲を狭める $("li.active") などの複合セレクターを使用します。
コンテキストを指定します: $("#parent .class")、$(".class",$el) など
4. イベント委任を使用する

使用シナリオ: 多数のレコードを含むリスト。マウスがクリックされた後に特定の機能を実装するには、各レコードをクリック イベントにバインドする必要があります。このアプローチでは、リスニング イベントが各レコードにバインドされます。ページ イベント リスナーが多数存在するため、非効率的になります。

基本原則: DOM 仕様内のイベントがバブルアップすることは誰もが知っています。つまり、イベントのバブルアップを積極的に防止しないと、任意の要素のイベントが DOM ツリーの構造に従って段階的に最上位までバブルアップします。 。イベント オブジェクトには、イベント ソースを指すevent.target (IE の srcElement) も用意されているため、親要素でイベントをリッスンしても、イベントをトリガーした元の要素を見つけることができます。これが基本原理です。代表団。早速、例を示します

上で紹介したイベント監視の原理に基づいて書き直してみましょう


もちろん、イベント ソースを毎回判断する必要はなく、それを抽象化してツール クラスに任せることもできます。 jquery の delegate() メソッドはこの関数を実装します

構文は $(selector).delegate(childSelector,event,data,function) のようになります。例:

コードをコピーします

コードは次のとおりです: $("div").delegate("ボタン","クリック",function(){ $("p").slideToggle(); });

パラメータの説明 (w3school から引用)
パラメータの説明
childSelector が必要です。イベント ハンドラーがアタッチされる 1 つ以上の子要素を指定します。
イベントは必須です。要素に付加する 1 つ以上のイベントを指定します。スペースで区切られた複数のイベント値。有効なイベントである必要があります。
データはオプションです。関数に渡す追加データを指定します。
必要な機能。イベントの発生時に実行する関数を指定します。
ヒント: イベント委任のもう 1 つの利点は、イベント バインド後に動的に追加された要素でトリガーされたイベントも監視できるため、ページに動的に追加されるたびに要素にイベントをバインドする必要がないことです

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。