序文 私は、Web サイトのフロントエンド パフォーマンス最適化のための JavaScript と CSS、jQuery プログラミングの標準的な記述方法とベスト プラクティスを含む、フロントエンド パフォーマンス最適化に関する以前に公開された記事を調べました。フロントエンドのパフォーマンス最適化は、継続的な追求のプロセスです。前回の記事ではパフォーマンス最適化についていくつか説明しましたが、パフォーマンス最適化にはまだ長い道のりがあり、言及されていないこともたくさんあります。今日は、これまでの基礎に基づいて、一般的に使用されるパフォーマンス最適化手法のいくつかを簡単にまとめます。 1. 演算子を使用する場合は、代入演算を直接実行するのではなく、+=、-=、*=、\= などの演算子を使用するようにしてください。 全般的な最適化 関数 getCategory(年齢) { var カテゴリー = ""; スイッチ(真){ isNaN(年齢)の場合: category = "年齢ではありません"; 壊す; ケース(年齢 >= 50 歳): カテゴリ = "古い"; 壊す; ケース(年齢 <= 20): カテゴリ = "赤ちゃん"; 壊す; デフォルト: カテゴリ = "若い"; 壊す; }; 返品カテゴリ; } getCategory(5); //赤ちゃん このような少し複雑なケースでは、if/else を使用しないようにしています。もちろん、単純な判断の場合は、if/else を使用することをお勧めします。 var str = "<div>これはテスト文字列です</div>"; /**効率が低い**/ var obj = document.getElementsByTagName("body"); (var i = 0; i < 100; i++){ obj.innerHTML += str + i; } /**高効率**/ var obj = document.getElementsByTagName("body"); var arr = []; (var i = 0; i < 100; i++){ arr[i] = str + i; } obj.innerHTML = arr.join(""); 3. メソッド文字列の代わりにメソッドを渡す /**非推奨**/ var i = 1; var j = "こんにちは"; var arr = [1,2,3]; var now = 新しい Date(); /**推進する**/ var i = 1, j = "こんにちは", arr = [1,2,3], now = 新しい日付(); 反復値を挿入 /**非推奨**/ var name = 値[i]; 私は++; /**推進する**/ var name = values[i++]; 配列とオブジェクトリテラルを使用し、コンストラクタArray()、Object()の使用は避けてください。 /**非推奨**/ var a = 新しい配列(); 0 = 1; a[1] = "こんにちは"; a[2] = 45; var o = 新しいオブジェクト(); o.name = "請求書"; o.年齢 = 13; /**推進する**/ var a = [1, "こんにちは", 45]; var o = { 名前:「ビル」、 年齢: 13 }; 型変換 1. 数値を文字列に変換します。 String() は内部関数なので非常に高速です。 .toString() はプロトタイプ内の関数を照会する必要があるため、若干遅くなります。 new String() が最も遅いです。 2. 浮動小数点数を整数に変換します。 /**効率が低い**/ var divs = document.getElementsByTagName("div"); for(var i = 0; i < divs.length; i++){ ... } /**効率が高く、DOM コレクションを取得するのに適しています。純粋な配列の場合は、2 つのケースにほとんど違いはありません**/ var divs = document.getElementsByTagName("div"); for(var i = 0, len = divs.length; i < len; i++){ ... } 2. ループ内で try-catch を使用しないでください。 試す { ( var i = 0; i < 200; i++) {} の場合 } キャッチ (e){} 3. 多数の要素のトラバースを避け、トラバース範囲を縮小するようにしてください。 関数呼び出し with ステートメントは独自のスコープを作成し、コードが実行されるスコープの長さを増加させます。 グローバルスコープ。 次のコードを例に挙げます。 var foo = 関数() { var ローカル = {}; }; 関数 foo(); console.log(local); //=> 未定義 var バー = 関数() { ローカル = {}; }; バー(); console.log(ローカル); //=> {} /**ここでは、foo() 関数と bar() 関数を定義します。どちらも local という変数を定義することを目的としています。 foo() 関数では、var ステートメントを使用してローカル変数を宣言し、関数本体内にスコープが形成されるため、この変数はそのスコープ内で定義されます。さらに、foo() 関数の本体ではスコープ拡張は実行されないため、関数の実行後にローカル変数も破棄されます。変数は外部スコープ内ではアクセスできません。 bar() 関数では、ローカル変数は var ステートメントを使用して宣言されていません。代わりに、local はグローバル変数として直接定義されています。したがって、外部スコープはこの変数にアクセスできます。 **/ ローカル = {}; // ここでの定義は global.local = {}; と同等です。 2. スコープチェーン 関数foo(){ var val = 'hello'; 関数バー() { 関数baz() { global.val = 'world;' }; バズ(); console.log(val); //=> こんにちは }; バー(); }; 関数 foo(); /** `JAVASCRIPT` では、変数識別子は現在のスコープから外側に向かってグローバル スコープまで検索されます。したがって、`JAVASCRIPT` コード内の変数へのアクセスは、外向きにのみ実行でき、逆向きには実行できません。 baz() 関数の実行により、グローバル スコープ内にグローバル変数 val が定義されます。 bar() 関数では、識別子 val にアクセスする場合、検索の原則は内側から外側に向かって行われます。つまり、bar 関数のスコープ内で見つからない場合は、上位層、つまり foo() 関数のスコープ内で検索されます。しかし、誰もが混乱する鍵はここにあります。この識別子アクセスは、foo() 関数のスコープ内で一致する変数を見つけ、外部の検索を続行しないため、baz() 関数で定義されたグローバル変数 val はこの変数アクセスには影響しません。 **/ 3. スコープチェーン上の検索回数を減らす /**効率が低い**/ (var i = 0; i < 10000; i++){ var but1 = document.getElementById("but1"); } /**高効率**/ /**グローバル検索を避ける**/ var doc = ドキュメント; (var i = 0; i < 10000; i++){ var but1 = doc.getElementById("but1"); } /** 上記のコードでは、2 番目のケースでは、まず関数内でグローバル オブジェクトの変数を保存し、その後変数に直接アクセスしますが、1 番目のケースでは、グローバル環境に到達するまでスコープ チェーンを毎回トラバースします。2 番目のケースは実際には 1 回しかトラバースされませんが、1 番目のケースは毎回トラバースされることがわかります。この違いは、マルチレベル スコープ チェーンと複数のグローバル変数の場合に非常に明白になります。スコープ チェーン内の検索回数は O(n) です。 `document` を指すローカル変数を作成することで、検索をグローバルなものに制限し、この関数のパフォーマンスを向上させることができます。 **/ 4. 終了 関数foo(){ var local = 'こんにちは'; 関数()を返す{ ローカルを返します。 }; } var bar = foo(); console.log(bar()); //=> こんにちは /** ここで示されている、外側のスコープが内側のスコープにアクセスできるようにする手法は、クロージャと呼ばれます。高階関数の適用により、foo() 関数のスコープが `拡張` されます。 foo() 関数は、foo() 関数のスコープ内に存在する匿名関数を返すため、foo() 関数のスコープ内のローカル変数にアクセスし、その参照を保存できます。この関数はローカル変数を直接返すため、bar() 関数を外部スコープで直接実行してローカル変数を取得できます。 **/ クロージャは、JAVASCRIPT の高度な機能です。内部変数参照を持つ関数を関数から取り出すため、関数の実行後、内部変数へのすべての参照が解放されるまで、スコープ内の変数は必ずしも破棄されるわけではありません。したがって、クロージャを適用すると、メモリが解放されなくなる可能性が高くなります。 ループバインディングイベントでは、6 つのボタンがあり、それぞれが 6 つのイベントに対応するというシナリオを想定します。ユーザーがボタンをクリックすると、対応するイベントが指定された場所に出力されます。 var btns = document.querySelectorAll('.btn'); // 6 つの要素 var 出力 = document.querySelector('#output'); var イベント = [1, 2, 3, 4, 5, 6]; // ケース1 (var i = 0; i < btns.length; i++) の場合 { btns[i].onclick = 関数(evt) { output.innerText += 'クリックされました' + events[i]; }; } /** ここでの最初の解決策は、明らかに典型的なループ バインディング イベント エラーです。ここでは詳細には触れません。詳細については、ネットユーザーへの私の回答を参照してください。2 番目と 3 番目の解決策の違いは、クロージャによって渡されるパラメーターにあります。 **/ // ケース2 (var i = 0; i < btns.length; i++) の場合 { btns[i].onclick = (function(index) { 関数(evt)を返す{ output.innerText += 'クリックされました' + events[index]; }; })(私); } /** 2 番目のソリューションでは、現在のループ インデックスがパラメーターとして渡されますが、後者のソリューションでは、対応するイベント オブジェクトが直接渡されます。実際、後者は大規模データ アプリケーションに適しています。JavaScript の関数型プログラミングでは、関数を呼び出すときに渡されるパラメーターは基本型オブジェクトであるため、関数本体で取得される仮パラメーターはコピーされた値になり、この値は関数本体のスコープ内でローカル変数として定義されます。イベント バインディングが完了したら、イベント変数を手動で逆参照して、外部スコープでのメモリ使用量を削減できます。さらに、要素が削除されると、対応するイベント リスニング関数、イベント オブジェクト、およびクロージャ関数も破棄され、リサイクルされます。 **/ //ケース3 (var i = 0; i < btns.length; i++) の場合 { btns[i].onclick = (function(イベント) { 関数(evt)を返す{ output.innerText += 'クリックされました' + イベント; }; })(イベント[i]); } 閉鎖の罠を避ける ;(function() { // メインビジネスコード})(); さらに高度なものもあります: ;(関数(win, doc, $, 未定義) { // メインビジネスコード})(window, document, jQuery); RequireJS、SeaJS、OzJS などのフロントエンドのモジュール読み込みソリューションでも同様の形式が採用されています。 /**JS が必要です**/ 定義(['jquery'], 関数($) { // メインビジネスコード}); /**SeaJS**/ 定義('モデル'、['dep'、'アンダースコア']、関数($、_) { // メインビジネスコード}); コールバック関数を有効活用する<br />Webページを作成する過程では、よく使う箇所を関数にカプセル化することがよく行われます。関数をカプセル化するときは、コールバック関数を有効に活用してください。 関数 getData(callBack){ $.ajax({ url:"", データ:{}、 データ型:"json", タイプ:"取得", 成功:関数(データ){ コールバック(null,データ) } }) } これを呼び出すと、次の操作を実行できます。 getData(関数(エラー,データ){ コンソール.log(データ) }) 配列に要素を挿入する最も速い方法<br />配列に要素を挿入することは、非常に一般的なタスクです。 push を使用して配列の末尾に要素を挿入したり、unshift を使用して配列の先頭に要素を挿入したり、splice を使用して配列の途中に要素を挿入したりできます。 しかし、これらの既知の方法は、より効率的な方法が存在しないことを意味するものではありません。 var arr = [1,2,3,4,5]; var arr2 = []; テストは次のとおりです。 arr[arr.length] = 6; // 最速 arr.push(6); // 34.66% 遅い arr2 = arr.concat([6]); // 85.79%遅い 要素を前に挿入 var arr = [1,2,3,4,5]; arr.unshift(0); [0].concat(arr); 発見する: [0].concat(arr); // 高速化 arr.unshift(0); // 64.70% 低速化 配列の中央に要素を追加する var items = ['1', '2', '3', '4']; items.splice(items.length / 2, 0, 'hello'); |
<<: ホバープロンプトにはvue2+elementuiを使用する
>>: 純粋な HTML タグにどれくらい精通していますか?
新しいプロジェクトは基本的に終了しました。フロントエンドとバックエンドを分離して統合を完了したのは初...
1. Windows 10 Enterprise Editionに付属する仮想マシンHyper-Vを...
1. CentOS8でのDockerのインストール カール https://download.doc...
チャレンジ:文字列内の文字 &、<、>、" (二重引用符)、および &...
目次01 非表示の列を作成する02 非表示の列に対する基本操作03 非表示の列メタデータ04 主キー...
ソングティ: SimSun太字: SimHeiマイクロソフト YaHei: マイクロソフト YaHe...
1. mysqlエクスポートファイル: SELECT `pe2e_user_to_company`....
以前、純粋な CSS を使用して波の効果を実現する方法をいくつか紹介しました。それらについては、次の...
Xiaobai は vmtools のインストールを記録します。 1. 意義と機能: VMWARE ...
概要リレーショナル データベースでは、インデックスは、データベース テーブル内の 1 つ以上の列の値...
voidキーワードの紹介まず、void キーワードは JavaScript で非常に重要なキーワード...
この記事ではMySQL 8.0.22のインストールと設定について記録します。具体的な内容は以下のとお...
現在、CentOS の最新バージョンは CentOS 8 です。次に、CentOS Linux 8....
目次1. シナリオ2. IJavaScriptShadowboxを実装する2.1 メインスレッドの実...
はじめに: すべてのデータを 1 つのテーブルに保存することのデメリット表の構成構造は複雑で不明瞭で...