スクリプトタグ-非同期および遅延


548

私は、属性についての質問のいくつ持ってasyncdeferのための<script>HTML5のブラウザで私の理解だけの仕事にタグを。

私のサイトの1つに、現在</body>タグのすぐ上にある2つの外部JavaScriptファイルがあります。最初は googleから供給され、2番目はローカルの外部スクリプトです。

サイトの読み込み速度に関して

  1. asyncページの下部にある2つのスクリプトに追加することで何か利点はありますか?

  2. async2つのスクリプトにオプションを追加し、それらをページの上部に配置すると、何か利点がありますか<head>

  3. これは、ページの読み込み時にダウンロードすることを意味しますか?
  4. HTML4ブラウザーでは遅延が発生すると思いますが、HTML5ブラウザーではページの読み込みが速くなりますか?

使用する <script defer src=...

  1. 2つのスクリプトを<head>属性付きでロードする と、defer以前のスクリプトと同じ効果があり</body>ますか?
  2. 繰り返しますが、これはHTML4ブラウザの速度を低下させると思います。

使用する <script async src=...

2つのスクリプトがasync有効になっている場合

  1. 同時にダウンロードしますか?
  2. または、ページの残りの部分を一度に1つずつですか?
  3. スクリプトの順序が問題になりますか?たとえば、1つのスクリプトが他のスクリプトに依存しているため、ダウンロードが速くなると、2番目のスクリプトが正しく実行されない可能性があります。

最後に、HTML5がより一般的に使用されるようになるまで、そのままにしておくのが最善でしょうか?


5
asyncは新しいものですがdefer、IE4からIEの一部になっています。defer最近、他のブラウザに追加されましたが、これらのブラウザの古いバージョンは、ぶらさがりが少ない傾向にあります。
Alohci、2012年

3
現在、HTML5は非常に人気があります。
2016

2
deferHTML の下部にスクリプトを配置するのと同じです。これは、長年にわたって一般的でした。
vsync 2018

1
@vsyncは必ずしもtrueとは限りません。ブラウザはスクリプトタグを解析するときにdeferタグを使用してJSをダウンロードしますが、DOMContentLoadedの直前まで実行を延期します。ダウンロードはノンブロッキングです。HTMLの下部に配置すると、DOMが構築されるまでJSのダウンロードと実行が遅延しますが、ダウンロードを待機することにより、さらに遅延が発生します。
Brad Frost

@BradFrost-インターネット帯域幅を使用しているという意味で、ダウンロードが私のビューでブロックされています。接続が遅い場合は、最初にドキュメントをロードし、それからレンダリングされたときにのみ、JavaScriptファイルのダウンロードを開始する必要があると思います。 。これは、コンテンツがすべて(SPAなど)をレンダリングするためにJavaScriptに密結合されていない場合に当てはまります
vsync

回答:


406

直前にスクリプトを保管してください</body>。Asyncは、いくつかの状況でそこにあるスクリプトで使用できます(以下の説明を参照)。いずれにしても、DOM解析作業はすでにほとんど行われているため、Deferはそこに配置されたスクリプトに大きな影響を与えません。

非同期と遅延の違いを説明する記事は次のとおりです:http : //peter.sh/experiments/asynchronous-and-deferred-javascript-execution-explained/

直前にスクリプトを本文の最後に置いておくと、HTMLは古いブラウザでより速く表示されます</body>。したがって、古いブラウザの読み込み速度を維持するために、それらを他の場所に配置したくない場合があります。

2番目のスクリプトが最初のスクリプトに依存している場合(たとえば、2番目のスクリプトは最初のスクリプトにロードされたjQueryを使用します)、実行順序を制御する追加のコードなしでそれらを非同期にすることはできませんが、据え置きスクリプトはドキュメントが解析されるまでは、まだ順番に実行されます。そのコードがあり、スクリプトをすぐに実行する必要がない場合は、スクリプトを非同期または遅延にすることができます。

<head>タグにスクリプトを入れて設定するdeferと、DOMが解析され、遅延をサポートする新しいブラウザでページが高速に表示されるまで、スクリプトの読み込みが遅延しますが、まったく役に立ちません。古いブラウザでは</body>、すべてのブラウザで機能するスクリプトを直前に配置するよりも速くはありません。だから、なぜそれらを直前に置くことが最善であるのかを理解することができます</body>

非同期は、スクリプトがいつ読み込まれるかを本当に気にせず、ユーザーに依存する他のものがスクリプトの読み込みに依存しない場合に、より便利です。非同期を使用するために最も頻繁に引用される例は、Google Analyticsのような分析スクリプトであり、何も待つ必要がなく、すぐに実行する必要はなく、単独で実行されるため、他に依存するものはありません。

通常、jQueryライブラリは非同期に適していません。他のスクリプトがそれに依存し、イベントハンドラーをインストールして、ページがユーザーイベントに応答し始め、初期状態を確立するためにjQueryベースの初期化コードを実行する必要がある場合があるためです。ページの。非同期で使用できますが、jQueryがロードされるまで実行されないように、他のスクリプトをコーディングする必要があります。


8
Deferはそれらを引き続き順番に実行する必要がありますが、dom-contentloadedの前に実行します。body htmlが解析される前にダウンロードを開始できるので、頭に入れておく方が速いという意味ではありませんか?
ケビン

9
スクリプトを配置しheadて設定することdefer</body>、以前に配置するよりも速くはないだろうと言っていましたが、私が読んだことからすると、それは誤りです。考えてみてください。スクリプトをに配置すると<head>、すぐにダウンロードが開始されますが、その直前であれば</body>、他のすべての要素が最初にダウンロードされます。
2014

12
@Nate-それは私のドキュメントの読み込みを速くしません。あなたはそれがスクリプトのロードをより早く改善する可能性があることは正しいですが、帯域幅の一部を使用し、ブラウザが特定のサーバーに対して行う制限された接続の1つを使用しているため、ドキュメントとそのコンテンツのロードを遅くする可能性もありますスクリプトがコンテンツを読み込もうとしている間にスクリプトを読み込みます。
jfriend00 14

4
「2番目のスクリプトが最初のスクリプトに依存している場合...非同期または延期にすることはできません」-これは真実ではなく、延期は順番に実行されます。
DisgruntledGoat 2014

2
この時点で、この回答が投稿された2012年以降のブラウザ開発では、</ body>要件は実際には必要ありません。
bgcode

843

この画像は、通常のスクリプトタグ、非同期、延期について説明しています

ここに画像の説明を入力してください

  • 非同期スクリプトは、スクリプトが読み込まれるとすぐに実行されるため、実行順序は保証されません(最後に含めたスクリプトは、最初のスクリプトファイルの前に実行される場合があります)

  • 据え置きスクリプトは、ページに表示される実行順序を保証します。

このリンクを参照してください:http : //www.growingwiththeweb.com/2014/02/async-vs-defer-attributes.html


複数のスクリプトを使用した例は、そのシーケンスを説明するのに適していると思います
vsync

4
@writofmandamus async勝つように見えます。stackoverflow.com/questions/13821151/…を
Monsignor

良い説明をありがとう。ただし、画像は実寸ではありません。<script>タグのみの場合、スクリプトファイルのダウンロードにかかる時間だけ、ページの読み込みの合計時間が長くなります。
アルニ

@BhavikHirani このサイトによると、同じスクリプトタグでasyncとdeferの両方を使用すると、ブラウザーがサポートしている場合はasyncを使用し、非同期がサ​​ポートされていないが遅延がサポートされている場合はフォールバックします。動作はかなり異なるため、結果は予測不可能であり、バグの優れた原因となる可能性があるため、両方を使用することはお勧めしません。
Adrian Wiik

@arni帯域幅が完全に利用されている場合のみ、ほとんど利用されません。また、どちらのダウンロードも帯域幅を共有し、1つをブロックすることはありません。—さらに:これらの画像は、解析ではなくダウンロードを緑で示しています。
Robert Siemer

213

HTML5: asyncdefer

HTML5では、JavaScriptコードを実行するタイミングをブラウザーに指示できます。3つの可能性があります。

<script       src="myscript.js"></script>

<script async src="myscript.js"></script>

<script defer src="myscript.js"></script>
  1. またはがないasync場合defer、スクリプトタグの下にある要素をレンダリングする前に、ブラウザはすぐにスクリプトを実行します。

  2. async(非同期)、ブラウザは、HTMLページをロードすると、ブラウザの負荷ながら、それをレンダリングし、同時にスクリプトを実行していきます。

  3. ではdefer、ブラウザはスクリプトのページ完成し、解析を実行します。(すべての画像ファイルのダウンロードを完了する必要はありません。これで十分です。)


async=""テンプレートの変更を検証して保存する前にblogger.comテンプレートが必要です。
noobninja

1
注:Asyncを使用して指定された順序でスクリプトが実行される保証はありません。「2番目のスクリプトが最初のスクリプトに依存している場合は、非同期を避けてください。」
Faisal Naseer

2
async-スクリプトは、ダウンロードされた瞬間に実行され、HTMLファイル内での順序は考慮されません。
vsync 2018

30

両方asyncdeferスクリプトがパーサとの両方のサポートオプションを一時停止することなく、すぐにダウンロードを開始しますonloadし、スクリプトに依存する初期化を実行するという一般的なニーズに対処するハンドラーを。

との違いは、スクリプトが実行されるタイミングasyncdefer中心にしています。各asyncスクリプトは、ダウンロードの終了後、ウィンドウのロードイベントの前に、最初の機会に実行されます。これは、asyncスクリプトがページに出現する順序で実行されない可能性があることを意味します。一方、deferスクリプトは、ページ内で発生した順に実行されることが保証されています。この実行は、解析が完全に終了した後、ドキュメントのDOMContentLoadedイベントの前に開始されます。

出典および詳細:こちら


25

同じ種類の問題に直面し、両方がどのように機能するかが明確に理解されました。この参照リンクがお役に立てば幸いです...

非同期

async属性をスクリプトタグに追加すると、次のようになります。

<script src="myfile1.js" async></script>
<script src="myfile2.js" async></script>
  1. ファイルをフェッチするために並列リクエストを行います。
  2. 中断されたことがないかのように、ドキュメントの解析を続行します。
  3. ファイルがダウンロードされた瞬間に、個々のスクリプトを実行します。

延期する

Deferはasyncと非常によく似ていますが、1つの大きな違いがあります。ブラウザがdefer属性を持つスクリプトに遭遇すると、次のようになります。

<script src="myfile1.js" defer></script>
<script src="myfile2.js" defer></script>
  1. 個々のファイルをフェッチするために並列リクエストを行います。
  2. 中断されたことがないかのように、ドキュメントの解析を続行します。
  3. スクリプトファイルがダウンロードされている場合でも、ドキュメントの解析を終了します。
  4. 各スクリプトは、ドキュメントでの出現順に実行します。

参照:非同期と遅延の違い


7

asyncそしてdeferHTML構文解析中にファイルをダウンロードします。どちらもパーサーを中断しません。

  • asyncダウンロードした属性付きのスクリプトが実行されます。一方、defer属性付きのスクリプトは、DOM解析の完了後に実行されます。

  • でロードされたスクリプトasyncは、順序を保証するものではありません。defer属性付きでロードされたスクリプトは、DOMに表示される順序を維持します。

<script async>スクリプトが何にも依存しない場合に使用します。スクリプトがuseに依存する場合。

最善の解決策は、ボディの下部にを追加することです。ブロッキングやレンダリングに問題はありません。


ここでいくつか明確にしたいのですが、ここで2つのことが起こっています。1.リソースのダウンロード2.リソースの実行。両方のケース(asyncとdefer)でのリソースのダウンロードはブロックされません。つまり、htmlの解析はブロックされませんが、asyncでの実行は解析をブロックし、deferの場合は、htmlマークアップが解析された後に実行されます。したがって、この場合は非ブロッキングです。
pOoOf 2018年

5

Jake Archibaldが2013年にトピックにさらにポジティブな印象を与えるかもしれない洞察をいくつか示してくれたと思います。

https://www.html5rocks.com/en/tutorials/speed/script-loading/

聖杯は、レンダリングをブロックせずにすぐに一連のスクリプトをダウンロードし、追加された順にできるだけ早く実行することです。残念ながらHTMLはあなたを嫌い、あなたにそれをさせません。

(...)

答えは実際にはHTML5仕様にありますが、スクリプトの読み込みセクションの下部には隠されています。" 非同期IDL属性は、要素が非同期で実行されるかどうかを制御します。要素の" force-async "フラグが設定されている場合、取得時に非同期IDL属性がtrueを返し、設定時に" force-async "が返される必要がありますフラグは最初に設定解除する必要があります... "。

(...)

動的に作成されてドキュメントに追加されるスクリプトは、デフォルトは非同期です。ダウンロードがすぐに実行されないため、レンダリングがブロックされず、間違った順序で実行される可能性があります。ただし、非同期ではないものとして明示的にマークすることができます。

[
    '//other-domain.com/1.js',
    '2.js'
].forEach(function(src) {
    var script = document.createElement('script');
    script.src = src;
    script.async = false;
    document.head.appendChild(script);
});

これにより、単純なHTMLでは実現できない動作がスクリプトに混在します。スクリプトは明示的に非同期ではないため、実行キューに追加されます。これは、最初のプレーンHTMLの例でスクリプトが追加されたキューと同じです。ただし、動的に作成されることにより、ドキュメントの解析の外部で実行されるため、ダウンロード中にレンダリングがブロックされることはありません(非同期XHRと非同期XHRの読み込みを混同しないでください。これは決して良いことではありません)。

上記のスクリプトは、ページの先頭にインラインで含める必要があり、プログレッシブレンダリングを中断することなくスクリプトダウンロードをできるだけ早くキューに入れ、指定した順序でできるだけ早く実行します。「2.js」は「1.js」より前に無料でダウンロードできますが、「1.js」が正常にダウンロードされて実行されるか、どちらかが失敗するまで実行されません。フラー!非同期ダウンロードですが、実行が順序付けられています

それでも、これはスクリプトをロードする最も速い方法ではない可能性があります。

(...)上記の例では、ブラウザはスクリプトを解析して実行し、ダウンロードするスクリプトを見つける必要があります。これにより、スクリプトがプリロードスキャナーから隠されます。ブラウザーはこれらのスキャナーを使用して、次にアクセスする可能性が高いページ上のリソースを検出したり、パーサーが別のリソースによってブロックされている間にページリソースを検出したりします。

これをドキュメントの先頭に置くことで、発見しやすさを追加できます。

<link rel="subresource" href="//other-domain.com/1.js">
<link rel="subresource" href="2.js">

これは、ページに1.jsと2.jsが必要であることをブラウザに伝えます。link [rel = subresource]はlink [rel = prefetch]と似ていますが、セマンティクスが異なります。残念ながら現在はChromeでのみサポートされており、リンク要素を介して1回、スクリプト内で2回ロードするスクリプトを宣言する必要があります。

修正:最初に、これらはプリロードスキャナーによって取得されたと述べましたが、そうではなく、通常のパーサーによって取得されました。ただし、プリロードスキャナーはこれらを取得できますが、まだ取得できません。実行可能コードに含まれているスクリプトをプリロードすることはできません。コメントで私を訂正してくれたYoav Weissに感謝します。


1

少なくとも実行フェーズでは、遅延と非同期の動作はブラウザに依存しているようです。注、延期は外部スクリプトにのみ適用されます。私は非同期が同じパターンに従うと仮定しています。

IE 11以前では、順序は次のようになっています。

  • async(ページの読み込み中に部分的に実行される可能性があります)
  • なし(ページの読み込み中に実行できます)
  • 延期(ページのロード後に実行、すべてファイルに配置された順に延期)

Edge、Webkitなどでは、async属性が無視されるか、最後に配置されるようです。

  • data-pagespeed-no-defer(ページの読み込み中に他のスクリプトの前に実行されます)
  • なし(ページの読み込み中に実行できます)
  • 延期(DOMがロードされるまで待機し、ファイル内の配置順にすべて延期します)
  • async(DOMが読み込まれるまで待機しているようです)

新しいブラウザーでは、data-pagespeed-no-defer属性が他の外部スクリプトよりも前に実行されます。これは、DOMに依存しないスクリプト用です。

注:外部スクリプトの実行の明示的な順序が必要な場合は、deferを使用してください。これは、ファイル内の配置順にすべての遅延スクリプトを実行するようにブラウザに指示します。

ASIDE:ロード時に外部JavaScriptのサイズが重要でしたが、実行順序には影響しませんでした。

スクリプトのパフォーマンスが心配な場合は、ミニファイを検討するか、XMLHttpRequestで動的にロードすることを検討してください。


data-pagespeed-no-deferサーバーサイド PageSpeedモジュールで使用される属性です。それdata-pagespeed-no-defer自体による属性は、どのブラウザにも影響しません。
Qtax
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.