Web パフォーマンスの最適化 - JavaScript パフォーマンスチューニング_JavaScript スキル
JavaScript は比較的完成度の高いフロントエンド開発言語であり、今日の Web 開発、特に Web 2.0 アプリケーションで広く使用されています。今日、Web 2.0 の人気がますます高まっているため、Web アプリケーション プロジェクトには大量の JavaScript コードが含まれるようになり、将来的にはさらに多くなるでしょう。 JavaScript は、解釈および実行される言語、およびそのシングルスレッド メカニズムとして、パフォーマンスが JavaScript の弱点であると判断されており、これは、Web ソフトウェア エンジニアが、特に Web 2.0 アプリケーションの場合に JavaScript を作成する際に細心の注意を払う必要がある問題でもあります。 Web ソフトウェア エンジニアの大多数は、多かれ少なかれ、開発した Web 2.0 アプリケーションのパフォーマンスが低下するという問題に遭遇したことがあります。主な原因は、不十分な JavaScript パフォーマンスと過負荷のブラウザです。ただし、このようなインタープリタ型のシングルスレッド言語のパフォーマンスの問題を解決するのは簡単ではありません。この記事では、開発中の JavaScript パフォーマンス チューニングのヒントとベスト プラクティスに焦点を当て、JavaScript 操作 DOM ノードのパフォーマンス チューニングのいくつかの方法についても説明します。
概要
パフォーマンスの問題についても説明します。 Web 開発、特に今日の Web2.0 アプリケーションで頻繁に遭遇する問題です。 JavaScript は、現在最も広く使用されている Web 開発言語です。Web アプリケーションのパフォーマンスの問題の大部分は、JavaScript 言語自体のパフォーマンスの問題や DOM のパフォーマンスの問題など、プログラマが作成した JavaScript スクリプトのパフォーマンスの低下によって引き起こされます。問題。この記事では主に、このような問題をできるだけ回避し、Web アプリケーションのパフォーマンスを最大化する方法について説明します。
JavaScript のパフォーマンス チューニング
JavaScript 言語にはシングルスレッドでインタープリタ型の実行特性があるため、パフォーマンス上の問題が多く、改善の余地があります。
eval の問題:
次のコードを比較してください:
リスト 1. eval の問題
varreference = {}, props = “p1”
eval(“reference.” props “=5”; )
varreference = {}, props = “p1”;
reference[props] = 5
「eval」を使用したコードは、「eval」を使用しないコードよりも 100 倍以上遅くなります” 。
主な理由は次のとおりです。JavaScript コードは、実行前に同様の「プリコンパイル」操作を実行します。まず、現在の実行環境でアクティブ オブジェクトを作成し、var で宣言された変数をアクティブ オブジェクトの属性として設定します。ただし、この時点では、これらの変数の割り当てはすべて未定義であり、 function で定義された関数もアクティブ オブジェクトの属性として追加され、それらの値は関数の定義とまったく同じになります。ただし、「eval」を使用すると、「eval」内のコード (実際には文字列) は事前にコンテキストを認識できず、事前に解析および最適化することができません。つまり、プリコンパイルされた操作を実行できません。したがって、そのパフォーマンスは大幅に低下します。
関数の使用法:
次のコードを比較します:
リスト 2. 関数の使用法
var func1 = new Function(“return argument[0] argument[1]”);
func1 (10, 20);
var func2 = function(){ return argument[0] argument[1] };
関数のスコープ チェーン: JavaScript コードは関数に入るときに解釈されて実行され、現在の変数が事前に分析され、これらの変数がさまざまなレベル (レベル) に分類されます。 )、一般的に言えば、
ローカル変数はレベル 1 (浅い) に配置され、グローバル変数はレベル 2 (深い) に配置されます。 「with」または「try - catch」コード ブロックを入力すると、新しいレベルが追加されます。つまり、「with」または「catch」の変数は最も浅いレベル (レベル 1) に配置され、以前のレベルは順番に深められます。
次のコードを参照してください。
リスト 3. 関数スコープ チェーン
… ..
function process(){
var image = document.getElementsByTagName("img"),
widget = document.getElementsByTagName("input"),
combination = [];
for(var i = 0; i
}
myObj.container.property1 = 組み合わせ[0];
myObj.container.property2 = 組み合わせ[combination.length-1]; 🎜> }
ここでは、「画像」、「ウィジェット」、および「組み合わせ」がレイヤー 1 のローカル変数に属していることがわかります。 「document」、「myObj」はレイヤー 2 のグローバル変数に属します。
変数が配置されている層が浅いほどアクセス (読み取りまたは変更) 速度は速くなり、深い層ほどアクセス速度は遅くなります。したがって、ここでの「画像」、「ウィジェット」、「組み合わせ」へのアクセス速度は、「ドキュメント」や「myObj」よりも高速です。したがって、次のコードに示すように、できる限りローカル変数を使用することをお勧めします。
リスト 4. ローカル変数の使用
var myObj = … ..
… ..
function process(){
var doc = ドキュメント;
var イメージ = doc.getElementsByTagName("img")、
ウィジェット = doc.getElementsByTagName("input")、
組み合わせ = []; 0; i combination(images[i], widget[2*i]));
myObj.container.property1 = 0];
myObj.container.property2 = combination.length-1];
}
グローバル変数 "document" の代わりにローカル変数 "doc" を使用します。特に多数のグローバル変数を使用する関数のパフォーマンスを向上させることができます。
リスト 5.
function process(){
var doc = document; .getElementsByTagName(" img"),
widget = doc.getElementsByTagName("input"),
combination = [];
for(var i = 0; i
}
with (myObj.container) {
property1 =組み合わせ
; property2 = combo[combination.length-1];
}
}
「with」キーワードを使用すると、コードがより簡潔かつ明確になりますが、パフォーマンスに影響します。 。前述したように、「with」コードブロックに入ると、元のレイヤー1からレイヤー2に「組み合わせ」が変わるため、効率が大幅に低下します。したがって、比較のために、引き続き元のコードを使用します。
var doc = document;
var image = doc; .getElementsByTagName( "img"),
widget = doc.getElementsByTagName("input"),
combination = [];
for(var i = 0; i
}
myObj.container.property1 = 組み合わせ[0]; combination[combination .length-1];
}
しかし、JavaScript にはオブジェクト オブジェクトの属性アクセス レベルが深くなるほど効率が低下するという特性があります。たとえば、ここでは「myObj」が 3 番目の層にアクセスしています。
リスト 7. オブジェクトのアクセス レベルを下げる
コードをコピーします
var image = doc.getElementsByTagName("img"),
widget = doc.getElementsByTagName("input"),
combination = []
for( var i = 0; i
combination.push(images[i], widget[2*i]));
var ctn = myObjコンテナ;
ctn.property1 = combination[0];
ctn.property2 = combination.length-1];
「myObj」「container」オブジェクトの 2 番目の層。オブジェクトの深いプロパティへのこのようなアクセスが多数ある場合は、上記のメソッドを参照してパフォーマンスを向上させることができます。
文字列関連
よく次のようなコードを目にします。
リスト 8. 単純な文字列の結合
コードをコピーします
これは文字列を結合する一般的な方法ですが、この方法では一部の一時変数が作成および破棄され、パフォーマンスに影響するため、次のメソッドを使用して結合することをお勧めします。
リスト 9. 文字列配列メソッド Splice
var str_array = [ ];
str_array.push("str1");
str = str_array.join(""); use array (array) の "join" メソッドは文字列のスプライシングを実装します。特に、古いバージョンの Internet Explorer (IE6) で実行する場合、非常に明らかなパフォーマンスの向上が見られます。
もちろん、最新のブラウザー (Firefox3、IE8 など) では文字列のスプライシングが最適化されており、次のように記述することもできます。
コードをコピーします
新しいブラウザは "= を最適化しており、配列の "結合" メソッドよりもパフォーマンスがわずかに高速です。近い将来、ブラウザの更新バージョンでも " " が最適化される可能性があるため、str = "str1" "str2" と直接書くことができます。
次のコードを参照してください:
リスト 11. 暗黙的な型変換
コードをコピー
ここで各ループで文字列を呼び出します「charAt」メソッドですが、「str」に定数「12345678」を代入しているため、ここでは「str」は実際には文字列オブジェクトではなく、「charAt」関数を呼び出すたびに一時的に値を構築します。 「12345678」の文字列オブジェクトを取得し、「charAt」メソッドを呼び出し、最後に文字列一時オブジェクトを解放します。
リスト 12. 暗黙的な型変換の回避
コードをコピー
このように、文字列オブジェクトとしての変数「str」には、この暗黙の型変換処理がありません。このようにして、効率が大幅に向上します。
文字列マッチング
JavaScript には、文字列の正規表現マッチングをサポートする RegExp オブジェクトがあります。素晴らしいツールですが、パフォーマンスはあまり良くありません。それどころか、「substring」、「indexOf」、「charAt」などの文字列オブジェクト (String) 自体のいくつかの基本メソッドは非常に効率的です。文字列を照合するために正規表現を使用する必要がある場合は、それを検討できます。 . :
文字列オブジェクト自体がサポートする基本的なメソッドで問題を解決することは可能ですか。
「部分文字列」を使用して正規表現の範囲を狭めることはできますか? これらの方法は、プログラムの効率を効果的に向上させることができます。 正規表現オブジェクトについては、もう 1 つ注意すべき点があります。次のコードを参照してください。
リスト 13. 正規表現
コードをコピー
ここで、 を渡します「 /^s*extras/」は効率に影響します。「/^s*extras/」の一時的な値を使用して正規表現オブジェクトを構築し、「match」メソッドを実行してから、一時的な正規表現オブジェクトを破棄します。
リスト 14. 変数の使用
コードをコピーします
}
この方法では、一時的なオブジェクトは存在しません。
setTimeout と setInterval
2 つの関数「setTimeout」と「setInterval」は文字列変数を受け入れることができますが、前述の「eval」と同様のパフォーマンスの問題が発生するため、これらを直接渡すことをお勧めします。オブジェクトそのもの。
早期終了の使用
次の 2 つのコードを参照してください。
リスト 15. 早期終了の利用
// コード 1
var name = … .;
var ソース = … ;
if(source.match(/ …… /)){
…………………………
}
//コード 2
var name = … .;
var source = …… ;
if(name.indexOf( … ) &&source.match(/ …… /)){
……… ………………………
}
コード 2 には、「name.indexOf(...)」に関する追加の判断があり、プログラムは最初に「indexOf」を実行します。 「このセクションに到達するたびに判定を行い、その後の match を実行します。これは、「indexOf」が「match」よりもはるかに効率的であることを前提としています。これにより、「match」の実行回数が減り、効率が向上します。ある程度。
----------------------------------------------- --- ----------------------------------
DOM 操作パフォーマンスのチューニング
JavaScript の開発は DOM 操作と切り離せないため、Web 開発では DOM 操作のパフォーマンス チューニングも非常に重要です。
再ペイントとリフロー
再ペイントは再描画とも呼ばれ、現在の DOM の構造とレイアウトに影響を与えない再描画アクションを指します。次のアクションは再描画アクションを生成します:
不可視から可視へ (可視性スタイル属性)
色または画像の変更 (背景、境界線の色、色のスタイル属性)
サイズ、形状、位置は変更しません。ただし、外観を変える変更
リフローは、再ペイントよりも重要な変更です。これは主に、DOM ツリーが操作されるときに発生し、DOM の構造とレイアウトが変更されるとリフローが発生します。ただし、要素の Reflow 操作が発生すると、その親要素と子要素がすべて Reflow を解放し、最終的に Reflow により Repaint が生成されます。たとえば、次のアクションは再描画アクションを生成します:
ブラウザ ウィンドウの変更
DOM ノードの追加および削除操作
サイズ、形状、およびサイズを変更するいくつかの操作ページ要素の位置 トリガー
リフローの削減
リフローと再ペイントの導入から、各リフローはその再ペイントよりも多くのリソースを消費することがわかります。リフローの発生を減らすか、リフローのみに変換する必要があります。トリガーの再描画操作のコード。
次のコードを参照してください:
リスト 16. リフローの概要
var pDiv = document.createElement(“div”);
document.body.appendChild(pDiv);----- reflow
var cDiv1 = document.createElement(" div");
var cDiv2 = document.createElement("div");
pDiv.appendChild(cDiv1);----- リフロー
pDiv.appendChild(cDiv2); ----- リフロー
これは私たちがよく目にするコードですが、このコードは 3 つのリフローを生成します。次のコードをもう一度見てください。
リスト 17. リフローの削減
var pDiv = document.createElement(“div”);
var cDiv1 = document.createElement(“div”);
var cDiv2 = document.createElement( "div");
pDiv.appendChild(cDiv2);
document.body.appendChild(pDiv);----- リフロー
🎜>ここでのリフローは 1 回だけなので、この方法で DOM ノードを操作することをお勧めします。
リスト 18. ディスプレイを使用してリフローを削減する
pDiv.appendChild(cDiv1);
pDiv.appendChild(cDiv3);
pDiv.appendChild(cDiv5);
pDiv.style.width = “100px”;
pDiv.style.display = “ブロック” --- リフロー
最初に pDiv を非表示にしてから表示することで、非表示と表示の間の操作でリフローが発生せず、効率が向上します。
特別な測定属性とメソッド
DOM 要素には、リフローをトリガーする特別な測定属性へのアクセスとメソッド呼び出しがいくつかあります。代表的なものは、「offsetWidth」属性と「getComputedStyle」メソッドです。
図 1. 特別な測定属性とメソッド

これらの測定属性とメソッドは、おおよそ次のとおりです:
offsetLeft
offsetTop
offsetHeight
offsetWidth
scrollTop/Left/Width/Height
clientTop/Left /Width/Height
getComputedStyle()
currentStyle(IE))
これらのプロパティとメソッドへのアクセスと呼び出しにより、リフローの生成がトリガーされます。これらのプロパティへのアクセスは最小限に抑える必要があります。
リスト 19. 特別な測定属性
var pe = document.getElementById(“pos_element”);
var result = document.getElementById(“result_element”); = pe.offsetWidth;
result.children[0].style.width = pOffsetWidth;
result.children[1].style.width = pOffsetWidth; = pOffsetWidth;
…………その他の変更…………
スタイル関連
よく次のコードを目にします。
リスト 20. スタイル関連
sElement.style.padding = ' 2px 3px '
sElement.style.marginLeft = ' 5px '
しかし、ここでスタイルを変更するたびにリフローが発生することがわかります。この状況の発生を減らすには、次のようにします。
:
リスト 21. className Solution
パディング: ' 2px 3px '
マージン左: ' 5px '
}
document.getElementById("pos_element").className = 'class1' ;
スタイルの代わりにクラスを使用すると、元のリフローまたは再ペイントの数を 1 つに減らすことができます。
解決策 2
リスト 22. cssText ソリューション
コードをコピー
ページには 1,000 を超えるページ要素が含まれることが多く、特定の要素を見つけるのにある程度の時間がかかることがよくあります。 ID または名前を使用して検索する場合、効率はそれほど遅くない可能性があります。要素の他の属性 (className など) を使用して検索する場合、効率は理想的ではない可能性があります。すべての要素 (getElementsByTagName) を走査してフィルタリングすることによってのみ対応する要素を見つけることができる場合もありますが、これはさらに非効率です。ここでは、多くのブラウザでサポートされている機能である XPath を使用して要素を見つけることをお勧めします。
リスト 23. XPath ソリューション
コードをコピーします
コードは次のとおりです。
if(document.evaluate){
var tblHeaders = document.evaluate(“//body/div/table//th”);
var result = tblHeaders.iterateNext(); 🎜>while(result) {
result.style.border = “1px 点線青”;
result ………………
result = xpathResult.iterateNext();
} else{ //getElementsByTagName() ……
// ブラウザが XPath をサポートしていない場合の状況を処理します
………………………………
}
ブラウザ XPath の検索エンジンは、検索効率を最適化し、結果が返される時間を大幅に短縮します。
HTMLCollection オブジェクト
これは特殊なタイプのオブジェクトで、配列に少し似ていますが、正確には配列ではありません。次のメソッドの戻り値は通常、HTMLCollection オブジェクトです: document.images、document.forms
getElementsByTagName()
getElementsByClassName()
これらの HTMLCollection オブジェクトは固定値ではなく、動的な結果。これらは一部の特殊なクエリの戻り値です。次の場合、前のクエリが再実行され、新しい戻り値 (クエリ結果) が得られますが、ほとんどの場合、それらは前のクエリと同じになります。または複数の戻り値:
長さ属性
特定のメンバー したがって、HTMLCollection オブジェクトによるこれらの属性およびメンバーへのアクセスは、配列のアクセスよりもはるかに遅くなります。もちろん例外もありますが、Opera と Safari は、パフォーマンスに大きな問題を引き起こすことなく、この状況をうまく処理します。
次のコードを参照してください。
リスト 24. HTMLConnection オブジェクト
…………………………
}
var items = document.getElementsByTagName(“div”);
for(var i = 0) ; i < items.length; i ){
……………………………… .
上記の方法は、各サイクルで "items.length" がトリガーされ、"document.getElementsByTagName(..)" メソッドが再度呼び出されるため、上記のものよりもはるかに効率的です。大幅に下がります。これは次のように解決できます。
………………………………………… .
}
このように、効率は基本的に普通の配列。
スクリプトタグを動的に作成する
リスト 26. スクリプト タグの作成

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック











JavaScript文字列置換法とFAQの詳細な説明 この記事では、javaScriptの文字列文字を置き換える2つの方法について説明します:内部JavaScriptコードとWebページの内部HTML。 JavaScriptコード内の文字列を交換します 最も直接的な方法は、置換()メソッドを使用することです。 str = str.replace( "find"、 "置換"); この方法は、最初の一致のみを置き換えます。すべての一致を置き換えるには、正規表現を使用して、グローバルフラグGを追加します。 str = str.replace(/fi

このチュートリアルでは、カスタムGoogle検索APIをブログまたはWebサイトに統合する方法を示し、標準のWordPressテーマ検索関数よりも洗練された検索エクスペリエンスを提供します。 驚くほど簡単です!検索をyに制限することができます

それで、あなたはここで、Ajaxと呼ばれるこのことについてすべてを学ぶ準備ができています。しかし、それは正確には何ですか? Ajaxという用語は、動的でインタラクティブなWebコンテンツを作成するために使用されるテクノロジーのゆるいグループ化を指します。 Ajaxという用語は、もともとJesse Jによって造られました

この記事シリーズは、2017年半ばに最新の情報と新鮮な例で書き直されました。 このJSONの例では、JSON形式を使用してファイルに単純な値を保存する方法について説明します。 キー価値ペア表記を使用して、あらゆる種類を保存できます

楽なWebページレイアウトのためにjQueryを活用する:8本質的なプラグイン jQueryは、Webページのレイアウトを大幅に簡素化します。 この記事では、プロセスを合理化する8つの強力なjQueryプラグイン、特に手動のウェブサイトの作成に役立ちます

コアポイント これは通常、メソッドを「所有」するオブジェクトを指しますが、関数がどのように呼び出されるかに依存します。 現在のオブジェクトがない場合、これはグローバルオブジェクトを指します。 Webブラウザでは、ウィンドウで表されます。 関数を呼び出すと、これはグローバルオブジェクトを維持しますが、オブジェクトコンストラクターまたはそのメソッドを呼び出すとき、これはオブジェクトのインスタンスを指します。 call()、apply()、bind()などのメソッドを使用して、このコンテキストを変更できます。これらのメソッドは、与えられたこの値とパラメーターを使用して関数を呼び出します。 JavaScriptは優れたプログラミング言語です。数年前、この文はそうでした

jQueryは素晴らしいJavaScriptフレームワークです。ただし、他のライブラリと同様に、何が起こっているのかを発見するためにフードの下に入る必要がある場合があります。おそらく、バグをトレースしているか、jQueryが特定のUIをどのように達成するかに興味があるからです

この投稿は、Android、BlackBerry、およびiPhoneアプリ開発用の有用なチートシート、リファレンスガイド、クイックレシピ、コードスニペットをコンパイルします。 開発者がいないべきではありません! タッチジェスチャーリファレンスガイド(PDF) Desigの貴重なリソース
