非同期JavaScriptと遅延

私の記事「Understanding the Critical Rendering Path」記事の翻訳 )で、JavaScriptファイルがCritical Rendering Path(CRP)に与える影響について書きました。







JavaScriptは、パーサーのブロッキングリソースです。 これは、JavaScriptがHTMLドキュメント自体の解析をブロックすることを意味します。 パーサーが<script>



到達すると(内部または外部)、停止し、ファイル(外部の場合)を取得して起動します。

ページに複数のJavaScriptファイルをロードすると、この動作により問題が発生する可能性があります。ドキュメントが実際にこれらのファイルに依存していない場合でも、最初のレンダリング時間が長くなるためです。







幸いなことに、 <script>



要素には2つのasync



およびdefer



属性があり、外部ファイルのロードおよび実行方法を制御できます。









通常の実行



これら2つの属性の違いを理解する前に、それらが存在しない場合に何が起こるかを見てみましょう。 前述のように、デフォルトでは、JavaScriptファイルはHTMLドキュメントを受け取って実行するまで解析を中断します。

<script>



要素がページの中央のどこかにある例を見てみましょう。







 <html> <head> ... </head> <body> ... <script src="script.js"> .... </body> </html>
      
      





パーサーがドキュメントを処理すると、次のようになります。









HTML解析は、スクリプトが読み込まれて実行されるまで一時停止されるため、最初のレンダリングまでの時間が長くなります。







async



属性



Async



、スクリプト非同期で実行できることをブラウザに伝えるために使用されます。

HTMLパーサーは、ロードして実行するために<script>



に到達したときに停止する必要はありません。 文書の解析と並行してスクリプトが受信された後、実行が発生する場合があります。







 <script async src="script.js">
      
      





この属性は、外部で接続されているファイルでのみ使用できます。 外部ファイルにこの属性がある場合、HTMLドキュメントの解析中にロードできます。 スクリプトファイルがロードされるとすぐに、パーサーが一時停止してスクリプトを実行します。









defer



属性



defer



属性は、HTMLドキュメントが完全に解析された後にスクリプトを実行するようブラウザに指示します。







 <script defer src="script.js">
      
      





非同期スクリプトのロードと同様に、HTMLドキュメントの解析中にファイルをロードできます。 ただし、パーサーの処理が完了する前にスクリプトファイルが完全に読み込まれた場合でも、パーサーが最後まで実行されるまで実行されません。









非同期、遅延、または通常の実行?



それでは、いつ非同期、遅延、または通常のJavaScript実行を使用する必要がありますか? いつものように、それは状況に依存し、正しい決定を下すのに役立ついくつかの質問があります。







<script>



要素はどこにありますか?



<script>



要素がドキュメントの最後にない場合、非同期実行と遅延実行が最も重要です。 HTMLドキュメントは、 <html>



を開いてから閉じるまで順番に解析されます。 終了</body>



直前に外部JavaScriptファイルが配置されている場合、その時点までにパーサーはドキュメントの大部分を既に解析し、JavaScriptファイルはそのファイルに影響を与えないため、 async



defer



使用は適切ではなくなります。







スクリプトは自給自足ですか?



他のファイルから独立しているファイルおよび/または依存関係がないファイルの場合、 async



属性が最も役立ちます。 ファイルがいつ実行されるかは関係ないので、非同期読み込みが最適なオプションです。







スクリプトは完全に解析されたDOMに依存していますか?



多くの場合、スクリプトファイルにはDOMと対話する関数が含まれています。 または、ページ上の別のファイルに依存している可能性があります。 そのような場合、スクリプトを実行する前にDOMを完全に解析する必要があります。 原則として、そのようなファイルはページの下部に配置され、その操作のためにすべてが解析されたことを確認します。 ただし、何らかの理由でファイルを別の場所に配置する必要がある状況では、 defer



属性が役立つ場合があります。







スクリプトは小さく、依存していますか?



最後に、スクリプトが比較的小さく、かつ/または他のファイルに依存している場合、インラインで識別する価値があるかもしれません。 組み込みコードはHTMLドキュメントの解析をブロックするという事実にもかかわらず、そのサイズが小さければあまり干渉しないはずです。 さらに、他のファイルに依存している場合は、わずかなロックが必要になる場合があります。







サポートと最新のブラウザーエンジン



async



およびdefer



サポートdefer



非常に一般的です:











これらの属性の動作は、JavaScriptエンジンによって多少異なる場合があることに注意してください。 たとえば、V8(Chromiumで使用)では、スクリプトの実行専用の個別のスレッドで、属性に関係なくすべてのスクリプトを解析しようとしました。 したがって、JavaScriptファイルの「ブロッキングパーサー」の性質は、デフォルトで最小限に抑える必要があります。








All Articles