JavaScriptファイルの非同期読み込み。 プロセスを加速および最適化し、生産性を向上

AJAXテクノロジーの最大限の使用に焦点を当てて、サイト(Webアプリケーション)の構築に関する一連の記事を続けています。 多くの場合、 AHAHを使用してサイトやアプリケーションを操作する場合、以前にサイトのページで使用されていなかったスクリプトファイルと、HTMLで読み込まれたコンテンツを読み込む必要があります。 AJAXでロードされたコンテンツを処理する側面の1つは、結果のコンテンツからスクリプトファイルを選択し、続いてそれらを現在のドキュメント(DOM)に適用することです。 幸いなことに、現時点では、ほとんどすべての主要なライブラリがこれを実行できます。 ただし、ロードされたスクリプトを処理するプロセスの実装をさらに深く掘り下げると、現在の状況は完全に「励みになりません」。 すべての有名なライブラリがこれをうまくできるわけではありません。 指定されたプロセスを内側から見て、既存の問題を分析し、それらを解決する方法を見つけましょう。



理解を容易にするために、AJAXを使用して追加のページを開始ページに読み込み、スクリプトページへのリンクが含まれる複雑な例を考えてみましょう。



そのため、開始ページで追加のページtest1.htmlをロードします。そのテキストは以下のとおりです

< html >

< head >

< script type ="text/javascript" src ="test1.js" ></ script >

<script type= "text/javascript" src= "test2.js" > </ script >

< link type ="text/css" rel ="stylesheet" href ="test.css" />

</ head >

< body >

Hello Bingo!

</ body >

</ html >








よく知られているjQueryライブラリを使用してこのページをロードします。 jquery1.htmlスタートページのテキストは以下のとおりです。

< html >

< head >

< script type ="text/javascript" src ="test1.js" ></ script >

<script type= "text/javascript" src= "jquery-1.2.6.js" ></script>

</head>

<body>

<div id= "content1" ></div>

<div id= "content2" ></div>

<script type= "text/javascript" >

$( function (){

$( '#content1' ).load( 'test1.html' )

$( '#content2' ).load( 'test1.html' )

})

</ script >

</ body >

</ html >










問題領域を特定するには、追加のページをそれぞれcontent1とcontent2のブロックに2回ロードします。



firebugコンソールには次のようなものが表示されます



GET test1.html

GET test1.html

GET test1.js?_ = 1239115065471

GET test2.js?_ = 1239115067323

GET test1.js?_ = 1239115068456

GET test2.js?_ = 1239115069347



ご覧のとおり、jQueryは、コンテンツを非同期的に読み込むときに、スクリプトがキャッシュされないように、スクリプトのアドレスに_ = 1239115067323のようなプレフィックスを追加します。 したがって、jQueryを使用する場合、ブラウザはキャッシュを使用せずに、完全なサイクルで毎回同じスクリプトを異なるページに再度ロードします。 問題は「理由」です。異なるページの同じスクリプト(同じアドレス)が実際に異なる可能性= 0です。したがって、スクリプトをリロードするプロセスは明らかに完全に考慮されていません。 ただし、この記事の目的はjQueryを批判することではありません。 状況は他のライブラリーと同様です。 この記事の目的は、スクリプトの非同期リロードプロセスの最適化の原理と方法を理解することです。



この記事では、非同期スクリプトの読み込みを最適化するための方法とオプションに関して、資料のより簡単なプレゼンテーションと理解のために、Fullajaxライブラリーのプロセスの最適化の実装について説明します。



最適化ステップ1-桟橋から開始



すでにメモリ内にあり、スタートページにロードされているものをロードするのはなぜですか?



test1.jsスクリプトは、スタートページで既に接続されていることに注意してください。 彼はすでに記憶しています。 したがって、サーバーから追加のデータをロードせずにコンテンツを取得するのは非常に簡単です。 したがって、最初に行うことは、スクリプトが既に標準の方法でページにロード(接続)されているかどうかを確認することです。 その場合は、その内容を取得して実行するだけです。 この例に関連して、示された簡単な操作を実行すると、サーバーへの2つの余分な要求がすぐになくなります。



最適化ステップ2-母なる苦しみの繰り返し



一度ダウンロードしたものをリロードするのはなぜですか?



firebug-aコンソールをもう一度見てみましょう。 jQueryを使用してスクリプトをダウンロードする順序と数に注意してください。 test1.jsおよびtest2.jsスクリプトはそれぞれ2回ダウンロードされます! 前のステップでtest1.jsスクリプトを調べました。 次に、2番目のスクリプトの読み込みを最適化します。 test2.jsスクリプトは、一度(一度)読み込み、その内容を「頬に」(ソフトウェアキャッシュに)入れて、サーバーからではなく、そこからすべてを取得するのに十分です。 したがって、この例に関連して、スクリプトのもう1つの余分な負荷と、それに応じたサーバーへの余分な要求を取り除きます。



要するに、単純な例を使用すると、「特定の」最適化が行われます。つまり、結果として、4つの初期要求のうち1つだけが要求されます。 上記の最適化手順は、デフォルトでFullajaxライブラリーで機能します。 つまり デフォルトでは、スタートページスクリプトは再読み込みされず、すべての新しいスクリプトは一度だけ読み込まれます。



fullajax.ru/temp/asyncjs/fullajax1.html



最適化ステップ#1の実装は、多少なりとも透過的です-headブロックですべてのスクリプトを見つけて、それらのコンテンツを取得します。 最適化ステップ2の実装には、サーバーからの並列非同期ページ要求間の追加の同期が必要でした。 多くの場合、最初のリクエストが終了する前に2番目のパラレルリクエストが開始された、つまり 2番目の要求は、スクリプトテキストを受け取る前に始まりました。 したがって、スレッド間の同期を確保する必要があります。これにより、最初のスレッドからのスクリプトのロードが完了すると、2番目のスレッドはすぐにそのことを認識します。 一般に、これはより詳細なトピックです...



幸運にも驚くべきことに、最適化オプションは未完成です。 不要な「動き」を引き続き除去できます。



最適化ステップ3-再初期化は最適化の敵



既に完了(初期化)したものを繰り返し実行(初期化)するのはなぜですか?



前の最適化手順では、スクリプトのリロードを取り除き、引き続き同じスクリプトを再実行します。 スクリプトtest1.jsおよびtest2.jsの内部を見てみましょう。



スクリプトtest1.js

var a = Math.random();





スクリプトtest2.js

function test(){

alert( 'Hello' );

}







test1.jsスクリプトに関しては、変数aの値がこれに依存するため、新しいロードごとに毎回実行することが重要です 。 ここでは何もできません。我慢してください。



test2.jsスクリプトについて-繰り返し実行してもペイロードはありません。 テスト関数はすでに1回定義されており、このスクリプトの後続のロードごとに、この関数は単純に再定義します。 したがって、このスクリプトを安全に再実行することはできません。 したがって、プロセッサ時間とメモリを節約できます。 ただし、スクリプトを1回だけ実行できるようにする即興の標準ツールはありません(HTML標準に準拠)。 これを行うには、スクリプトの内部構造を変更して以前の実行を確認するか、適切なアルゴリズムで非同期スクリプトの読み込みのエンジン(ライブラリ)を付与する必要があります。

Fullajaxでのこの最適化手順の実装を検討してください。 一部のスクリプトを1回だけ実行するには、「マジック」属性ax:repeat = '0'をスクリプトに追加する必要があります

< script type ="text/javascript" ax:repeat ="0" src ="test2.js" ></ script >



そしてそれだけです:)。 さらに、スクリプト読み込みアルゴリズムは、そのようなタグ付きスクリプトの実行を自動的に最適化します。 そのようなスクリプトは一度だけ実行されます。 スクリプトの繰り返し実行(初期化)の必要性の有無は、開発者が決定します。 スクリプトを分析してください! 繰り返し実行する必要がない場合は、対応する属性で自由にマークしてください。 場合によっては、個々のスクリプトを繰り返し実行すると、サイト(Webアプリケーション)でエラーが発生することさえあります。 このような例は、よく知られているカレンダースクリプト( Zapatec Calendar )です。 AJAXコンテンツの読み込み中に一連のスクリプトからcalendar.jsスクリプトを繰り返し実行すると、カレンダーが機能しなくなり、エラーがスローされます。



疲れていない? 私は、説明に少し「疲れ」ました...上記のどれだけがプログラムされたか想像してください:)。



そして、これは最適化のすべての可能な方法ではなく、非同期スクリプトの読み込みで最適化できるものがまだあります。



最適化ステップ4-Parallelsの歌



ロードされたページにいくつかのスクリプトがある場合を見てみましょう。 例えば

< html >

< head >

< script type ="text/javascript" src ="test1.js?1" ></ script >

<script type= "text/javascript" src= "test1.js?2" ></script>

<script type= "text/javascript" src= "test1.js?3" ></script>

<script type= "text/javascript" src= "test1.js?4" ></script>

<script type= "text/javascript" src= "test1.js?5" ></script>

<script type= "text/javascript" src= "test1.js?6" ></script>

<script type= "text/javascript" src= "test1.js?7" ></script>

<script type= "text/javascript" src= "test1.js?8" ></script>

<script type= "text/javascript" src= "test1.js?9" ></script>

<script type= "text/javascript" src= "test1.js?10" > </ script >

</ head >

< body >

Hello Bingo!

</ body >

</ html >






この場合のjQueryは最初のスクリプトのロードを開始し、最初のスクリプトの最後に2番目のスクリプトのロードを開始し、2番目のスクリプトのロードの最後に3番目のスクリプトをロードします。 つまり 実際、スクリプトの同期順次ロードが実行されます。



fullajax.ru/temp/asyncjs/jquery2.html



そして、これは非常に正常です! すべてのブラウザは、標準のスクリプトをロードしても同じように動作します。 後続のスクリプトの実行は前のスクリプトに依存する可能性があるためです。 したがって、最初を待ってから2番目を実行する必要があります。

しかし! 実行することは、ロードすることとまったく同じではありません。 結局のところ、すべてのスクリプトの並列ロードを実行できますか?..しかし、ロードされると、それらはすでに順次実行されます。

したがって、上記のアルゴリズムを実装すると、本当に安全な非同期スクリプトの読み込みが可能になります。 この最適化アルゴリズムは、順次使用の並列ロードアルゴリズムと呼ばれます



fullajax.ru/temp/asyncjs/fullajax2.html



実際の条件に近い状態で、大きなスクリプトファイルを読み込みます。



jQuery



fullajax.ru/temp/asyncjs/jquery3.html



フラージャックス



fullajax.ru/temp/asyncjs/fullajax3.html



結論は明らかです。



指定されたスクリプト読み込み最適化アルゴリズムはFullajaxライブラリに実装され、デフォルトで使用されます。



そしてもう少し最適化-スキップ〜奇跡を実行



AJAXを使用してコンテンツをロードするとき、特定のスクリプトの実行を無効にすると同時に、通常の標準ロードで通常の実行を実行することが必要になる場合があります。 これを行う簡単な標準的な方法はありません。 指定された機能を実装するには、サーバー上でコンテンツがどのようにリクエストされるかを決定する必要があります(AJAXまたは標準的な方法を使用)。これに従って、ページコンテンツに特定のスクリプトを追加または削除します。 Fullajaxを使用する場合、はるかに簡単な方法があります-axスタイルに「素晴らしい」属性を追加します:skip = '1' 。 これで、ライブラリは、それに応じてマークしたスクリプトをスキップ(無視)し、ロードも試行しなくなります。



さまざまなライブラリのスクリプトの処理に関して、他にも多くの質問があります。 たとえば、ロードされたドキュメントで最初にスクリプトを実行することが明確に示されている場合、jQueryが最初にコンテンツを挿入してからスクリプトを実行し、次にコンテンツを貼り付ける理由。 この記事の範囲を超えている他のポイントもあります。



この記事では、スクリプトを使用したHTMLコンテンツの非同期ロード中に発生するさまざまなボトルネックを詳細に分析および分析し、そのようなボトルネックを最適化する方法を検討しました。



記事の内容は独特であり、カバーされたり声を出したことはなく、初めて公開されます。 すべての結論とアルゴリズムは、Fullajaxライブラリーの開発中に記事の著者によって推測されました



jQuery私も大好きです:)。



UPD: -大きなスクリプトファイルを読み込む際のテストを追加しました。



All Articles