ブラウザでのJavaScriptのパフォーマンスは、フロントエンド開発者が直面しなければならない最も重要なユーザビリティの問題であると言えます。
YahooのYSLOW23ルールの中で、そのうちの1つはJSを下部に置くことです。その理由は、実際には、ほとんどのブラウザが単一のプロセスを使用してUIやUpated JavaScriptの実行などの複数のタスクを処理し、同時に1つのタスクのみが実行されるためです。 JavaScriptはどのくらいの期間実行され、ブラウザがユーザーのインタラクションに応答するまでにアイドル状態になるまで待つのにどれくらい時間がかかりますか。
基本的な観点から、これは<script>タグの外観がスクリプトの解析と実行のためにページ全体を待つことを意味します。実際のJavaScriptコードが無関係な外部ファイルにインラインドされているか、含まれているかに関係なく、ページのダウンロードと解析プロセスを停止し、継続する前にスクリプトがこれらの処理を完了するのを待つ必要があります。これは、スクリプトが実行時にページコンテンツを変更する可能性があるため、ページのライフサイクルの重要な部分です。典型的な例は、document.write()関数です。
コードコピーは次のとおりです。
<html>
<head>
<title>スクリプトの例</title>
</head>
<body>
<p>
<script type = "text/javascript">
document.write( "日付は" +(new date())。TODATESTRING());
</script>
</p>
</body>
</html>
上記のHTMLページのように、ブラウザがA <script>タグに遭遇すると、JavaScriptが<P>タグにコンテンツを追加するかどうかを予測することは不可能です。したがって、ブラウザは停止し、このJavaScriptコードを実行してから、ページを解析して翻訳し続けます。 SRCプロパティを使用してJavaScriptをロードする場合も同じことが起こります。ブラウザは、最初に外部ファイルのコードをダウンロードする必要があります。これには時間がかかり、次にこのコードを解析して実行する必要があります。このプロセス中、ページの解析とユーザーの相互作用は完全にブロックされます。
スクリプトは他のページリソースのダウンロードプロセスをブロックするため、推奨される方法は次のとおりです。すべての<body>タグの下部に近いものとして、ページ全体のダウンロードへの影響を最小限に抑えることです。例えば:
コードコピーは次のとおりです。
<html>
<head>
<title>スクリプトの例</title>
<link rel = "styleSheet" type = "text/css" href = "styles.css">
</head>
<body>
<p> hello world!</p>
< - 推奨されるスクリプトの位置決めの例 - >
<script type = "text/javascript" src = "file1.js"> </script>
<script type = "text/javascript" src = "file2.js"> </script>
<script type = "text/javascript" src = "file3.js"> </script>
</body>
</html>
このコードは、推奨される<script>タグがHTMLファイルにある場所を示しています。スクリプトのダウンロードは互いにブロックされていますが、ページはユーザーの前でダウンロードおよび表示されており、ページに入力する速度は遅すぎません。これは、JSを下に置くために上記のことです。
さらに、Yahoo! 「Yahoo!ユーザーインターフェイス、Yui」ライブラリの「連邦ハンドル」を作成します。これは、「コンテンツ配信ネットワーク(CDN)を介して実装されています。どのWebサイトでも「Federal Handle」URLを使用して、Yuiファイルパッケージに含まれているファイルを示すことができます。たとえば、次のURLには2つのファイルが含まれます。
コードコピーは次のとおりです。
<script type = "text/javascript" src = "http://yui.yahooapis.com/combo?2.7.0/build/yahoo/yahoomin.js&2.7.0/build/event/event-min.js"> </script
このURLは、バージョン2.7.0のYahoo-min.jsおよびevent-min.jsファイルを呼び出します。これらのファイルはサーバー上の2つの個別のファイルですが、サーバーがこのURL要求を受信すると、2つのファイルがマージされてクライアントに返されます。このようにして、2つの<script>タグが不要になり(タグごとに1つのファイルがロードされます)、1つの<script>タグがロードできます。これは、HTMLページに複数の外部JavaScriptを含める最良の方法です。
ノーブロッキングスクリプト
上記は、ページの初期状態に複数のJavaScriptスクリプトをロードする最良の方法です。 JavaScriptは、開発者が直面する最も重要なパフォーマンスの問題であるHTTPリクエストやインターフェイスリフレッシュなど、特定のブラウザ処理プロセスをブロックする傾向があります。 JavaScriptファイルを短く保ち、HTTPリクエストの数を制限することは、レスポンシブWebアプリケーションを作成するための最初のステップにすぎません。
しかし、多くのJSコードを備えた大規模なWebページなど、ソースコードを短く保つことが必ずしも最良の選択ではありません。したがって、非ブロックスクリプトが生まれました。必要なのは、javaScriptをページに徐々に追加することです。これは、ブラウザをある程度ブロックしません。
スクリプトをブロックしないための鍵は、ページのロード後にJavaScriptソースコードをロードすることです。つまり、ウィンドウのロードイベントが発行された後にコードのダウンロードが開始されます。
関連する説明:
ウィンドウの負荷イベントは、ページが読み込まれた後に1回しか発射されません。
window.onload = function(){}は、Webページ内のすべてのコンテンツが実行されるのを待機する必要があります(写真などの要素のすべてのファイルを含む)、つまり、JavaScriptはこの時点でページの任意の要素にアクセスできます。
次の方法は次のとおりです。
スクリプトが延期されたスクリプトを延期しました
HTML4は、<script>タグ:Deferの拡張属性を定義します。
この延期属性は、要素に含まれるスクリプトがDOMを変更するつもりはないため、コードを後で実行できることを示しています。 Defer属性は、Internet Explorer 4+およびFirefox 3.5+によってのみサポートされており、理想的なクロスブラウザーソリューションではありません。他のブラウザでは、延期属性は無視されます。したがって、<script>タグは通常のデフォルトの方法で処理されます。つまり、閉塞を引き起こします。さまざまな主流のブラウザでサポートされている場合、これは依然として効果的なソリューションです。
コードコピーは次のとおりです。
<script type = "text/javascript" src = "file1.js" defer> </scrip>
Defer属性を備えた<script>タグは、ドキュメント内のどこにでも配置でき、DOMがロードされるまで解析されるとダウンロードを開始できます(オンロードイベントハンドルが呼び出される前)。延期JavaScriptファイルがダウンロードされた場合、ブラウザ内の他の処理プロセスをブロックしないため、これらのファイルは他のリソースと並行してダウンロードできます。
次のコードを使用して、ブラウザが延期属性をサポートするかどうかをテストできます。
コードコピーは次のとおりです。
<html>
<head>
<Title>スクリプト延期例</title>
</head>
<body>
<Script Defer> alert( "Defer"); </script>
<script> alert( "script"); </script>
<script> window.onload = function(){alert( "load");}; </script>
</body>
</html>
ブラウザがDeferをサポートしていない場合、ポップアップダイアログボックスの順序は「延期」、「スクリプト」、および「ロード」です。
ブラウザがDeferをサポートする場合、ポップアップダイアログボックスの順序は「スクリプト」、「ロード」、「延期」です。
動的なスクリプト要素
DOMを使用すると、JavaScriptを使用してHTMLのほぼすべてのドキュメントコンテンツを動的に作成でき、標準DOMを使用して新しい<script>要素を非常に簡単に作成できます。
コードコピーは次のとおりです。
1 var script = document.createelement( "script");
2 script.type = "text/javascript";
3 Script.src = "file1.js";
4 document.body.appendChild(スクリプト);
new <script>要素は、file1.jsソースファイルをロードします。要素がページに追加された直後にこのファイルをダウンロードします。このテクノロジーの重要なポイントは、ダウンロードがどこで開始されても、ファイルのダウンロードと実行が他のページ処理をブロックしないことです。
ダイナミックスクリプトノードを使用してファイルがダウンロードされると、通常、返されたコードはすぐに実行されます(FirefoxとOperaを除き、以前のすべての動的スクリプトノードが実行されるのを待ちます)。
ほとんどの場合、JavaScriptファイルの動的ダウンロードを実装するための関数を呼び出したいと考えています。次の関数のカプセル化により、標準の実装とIE実装が実装されます。
コードコピーは次のとおりです。
function loadscript(url、callback){
var script = document.createelement( "script");
script.type = "text/javascript";
if(script.readystate){// ie
script.onreadystatechange = function(){
if(script.readystate == "loaded" || script.readystate == "complete"){
script.oneadystatechange = null;
折り返し電話();
}
};
}
else {//その他
script.onload = function(){callback();
};
}
script.src = url;
document.getElementsByTagname( "head")[0] .appendChild(script);
}
loadscript( "file1.js"、function(){// call
alert( "ファイルはロードされています!");
});
この関数は、JavaScriptファイルのURLと、JavaScript受信が完了したときにトリガーされるコールバック関数の2つのパラメーターを受け入れます。属性チェックは、監視するイベントを決定するために使用されます。最後のステップは、SRC属性をヘッドにJavaScriptファイルを追加することです。
ダイナミックスクリプトロードは、クロスブラウザーであり、使いやすいため、非ブロッキングJavaScriptのダウンロードで最も一般的に使用されるパターンです。
XMLHTTPREQUESTスクリプトインジェクションXHRスクリプトインジェクション
ノンブロッキングの方法でスクリプトを取得する別の方法は、xmlhttprequest(xhr)オブジェクトを使用してスクリプトをページに挿入することです。この手法は最初にXHRオブジェクトを作成し、次にJavaScriptファイルをダウンロードし、次にJavaScriptコードをDynamic <script>要素でページに挿入します。デモを見てください:
コードコピーは次のとおりです。
var xhr = new xmlhttprequest();
xhr.open( "get"、 "file1.js"、true);
xhr.onedeadystatechange = function(){
if(xhr.readystate == 4){
if(xhr.status> = 200 && xhr.status <300 || xhr.status == 304){// HTTPステータスコードを確認してください
var script = document.createelement( "script");
script.type = "text/javascript";
script.text = xhr.responsetext;
document.body.AppendChild(スクリプト);
}
}
};
xhr.send(null);
このコードは、file1.jsを取得するためにファイルGetリクエストをサーバーに送信します。 onreadystatechangeイベントハンドラーは、ReadyStateが4かどうかを確認し、HTTPステータスコードが有効かどうかを確認します(クライアント要求が成功したことを確認し、2xxは有効な応答を意味し、304はキャッシュされた応答を意味します)。有効な応答が受信されると、新しい<script>要素が作成され、そのテキスト属性がサーバーから受信された応答文字列に設定されます。そうすることで、実際にインラインコードを使用して<script>要素が作成され、新しい<script>要素がドキュメントに追加されると、コードが実行され、使用できます。
この方法の利点は、適切な互換性があり、すぐに実行されないJavaScriptコードをダウンロードできることです。コードは<script>タグの外側に戻るため、ダウンロード後に自動的に実行されることはありません。これにより、実行を延期できます。
この方法の決定は、ブラウザの相同制限の対象となります。 JavaScriptファイルはページと同じドメインに配置する必要があり、CDN(コンテンツ配信ネットワーク)からダウンロードすることはできません。このため、大規模なWebページは通常、XHRスクリプトインジェクションテクノロジーを使用しません。
推奨ノーブロッキングパターン推奨ノーブロッキングパターン
大量のJavaScriptをページにロードする推奨方法は、2つのステップに分割されます。
最初のステップには、JavaScriptを動的にロードするために必要なコードが含まれ、ページ初期化に必要なJavaScriptを除く部品をロードします。コードのこの部分は可能な限り小さく、loadscript()関数のみを含めることができます。ダウンロードして非常に迅速に実行され、ページにあまり干渉しません。
2番目のステップは、最初のコードの準備ができた後、残りのJavaScriptをロードするために使用することです。
例えば:
コードコピーは次のとおりです。
1 <script type = "text/javascript" src = "loader.js">
2 </script> <script type = "text/javascript">
3 loadscript( "therest.js"、function(){
4 Application.init();
5});
6
7 </script>
このコードを体の密接なタグの前に配置します</body>。これを行うことの利点は、最初に、JavaScriptが他のページの他の部分に影響を与えることなく実行することを保証することです。第二に、JavaScriptファイルの2番目の部分がダウンロードされると、アプリケーションに必要なすべてのDOMが作成され、アクセスする準備ができており、ページの準備が整っているかどうかを知るために追加のイベント処理(window.onloadなど)の使用を回避します。
別のオプションは、LoadScript()機能をページに直接埋め込むことです。これにより、HTTP要求のオーバーヘッドが減少します。例えば:
コードコピーは次のとおりです。
1 <script type = "text/javascript">
function loadscript(url、callback){
var script = document.createelement( "script");
script.type = "text/javascript";
if(script.readystate){// ie script.onreadystatechange = function(){
if(script.readystate == "loaded" || script.readystate == "complete"){
script.oneadystatechange = null;
折り返し電話();
}
};
} else {//その他
script.onload = function(){
折り返し電話();
};
}
script.src = url;
document.getElementsByTagname( "head")[0] .appendChild(script);
}
loadscript( "therest.js"、function(){
application.init();
});
</script>
ページの初期化コードがダウンロードされたら、loadscript()関数を使用して、ページで必要な追加の関数関数をロードすることもできます。
一般的なツール、Yahoo!のRyan Groveを紹介します検索Lazyloadライブラリを作成しました(http://github.com/rgrove/lazyload/を参照)。 lazyloadは強力なloadscript()関数です。 Lazyloadは、スケーリング後に約1.5kbのみです。使用法の例は次のとおりです。
コードコピーは次のとおりです。
<script type = "text/javascript" src = "lazyload-min.js"> </scrip>
<script type = "text/javascript">
lazyload.js( "the-rest.js"、function(){
application.init();
});
</script>
まとめ
1。ページの下部にすべての<script>タグを配置します</body>に近い。この方法により、スクリプトが実行される前にページが解析されることが保証されます。
2。スクリプトをグループにパックします。ページ上の<script>タグが少ないほど、ページがより速く読み込まれ、より速く応答します。これは、外部スクリプトファイルとインラインコードの両方に当てはまります。
3.非ブロッキングメソッドを使用してJavaScriptをダウンロードする方法はいくつかあります。
1)。 <script>タグに延期属性を追加します
2)。 <script>要素を動的に作成し、それを使用してコードをダウンロードして実行します
3)。 XHRオブジェクトを使用してコードをダウンロードし、ページに注入します
上記の戦略を通じて、JavaScriptコードを使用するネチズンの実際のパフォーマンスを大幅に改善できます。
参照帳「高性能JavaScript」。