<script defer =“ defer”>はどのように機能しますか?


208

いくつかの<script>要素があり、それらのいくつかのコードは他の<script>要素のコードに依存しています。このdefer属性は、コードブロックの実行を延期できるため、ここで役立ちます。

それをテストするために、私はこれをChromeで実行しました:http : //jsfiddle.net/xXZMN/

<script defer="defer">alert(2);</script>
<script>alert(1)</script>
<script defer="defer">alert(3);</script>

ただし、アラートが表示され2 - 1 - 3ます。警告しないのはなぜ1 - 2 - 3ですか?


2
多分この記事をチェックしてください。そして、いつものように、IEは何かが何を意味するかについて独自の考えを持っており、最初にスクリプトをロードすることを決定しましたが、本体がロードされるまで(通常)実行を遅らせます。
ブラッドクリスティ

おかげで、テストページのChromeでの結果は異なります:websiteoptimization.com/speed/tweak/defer/test。スクリーンショットは私がそれをどのように期待するかを示していますが、Chromeは遅延オブジェクトを最初に実行しているようです。
pimvdb 2011年

1
IEの遅延の定義は、DOMレベル1仕様のW3Cの遅延の意図と一致していると思います。
Mark At Ramp51

41
Alohciが彼の回答ですでに指摘したように、HTML標準に よると、をdefer指定する場合にのみ有効ですsrc。これが、ほとんどのブラウザーで期待どおりに機能しない例である可能性があります。
Pankrat、2011年

2
@Pankrat実話!jsfiddle.net/xXZMN/50を試すFirefox24でテスト済み
m93a

回答:


51

更新日:2016年2月19日

この回答は古くなっていると考えてください。新しいブラウザーバージョンに関連する情報については、この投稿の他の回答を参照してください。


基本的に、deferはブラウザに、スクリプトブロックでJavaScriptを実行する前に「準備ができるまで」待機するように指示します。通常、これはDOMの読み込みとdocument.readyState == 4が完了した後です。

defer属性はInternet Explorerに固有です。Internet Explorer 8では、Windows 7でJS Fiddleテストページに表示される結果は1-2-3です。

結果はブラウザによって異なる場合があります。

http://msdn.microsoft.com/en-us/library/ms533719(v=vs.85).aspx

一般に信じられていることとは逆に、IEは一般に認められているよりも頻繁に標準に従いますが、実際には「defer」属性はDOM Level 1仕様で定義されていますhttp://www.w3.org/TR/REC-DOM-Level-1/level -one-html.html

W3Cによる遅延の定義:http : //www.w3.org/TR/REC-html40/interact/scripts.html#adef-defer

「設定すると、このブール属性は、スクリプトがドキュメントコンテンツを生成しない(たとえば、JavaScriptの "document.write"がない)ため、ユーザーエージェントにヒントを提供するため、ユーザーエージェントは解析とレンダリングを続行できます。」


8
@ MarkAtRamp51-回答が古くなっている場合は、他の回答のコメントの反対票について不満を言うのではなく、編集する必要があります。反対票は、「役に立たない」回答のためのものです。
Christian Conkle、2015年

10
@ChristianConkleエチケットのレッスンに感謝しますが、ここでの他の回答は最新です。質問がなされたときに間違った答えが選択されなかったという事実に対処していました。おそらく、時間の経過とともに物事が変化することを人々に思い出させようとするのではなく、コミュニティが回答を不適切に選択するという誤った評価を広める人々を警戒する必要があります。コンテキストは重要です。履歴情報も貴重であるため、私の答えを削除しても意味がありません。
Mark At Ramp51 2015年

3
「履歴情報も貴重なので、回答を削除しても意味がありません」その場合は、HTML5より前のバージョンにのみ適用されることを指摘し、「正しい」(最新)回答?これにより、多くの問題を回避できます(「間違った」回答が一度も受け入れられ、最終的にそれを変更するように「プレッシャーをかけられた」人と言えます)。
mgibsonbr 2015

3
@Leoはフラグを立ててはいけませんか?「html5遅延スクリプト」を検索すると、これはGoogleの3番目の結果です。この答えは、多くのユーザーに古くて間違った定義を提供しています。(現在の定義:「ユーザーエージェントがスクリプトの処理を延期できることを示します。HTML4.0のdefer属性の定義を参照してください。」)
Malavos

2
@ MarkAtRamp51私はあなたの答えを更新するべきだと思います。この質問を見つけてあなたの答えを見つけた人は、その履歴情報を認識しません。今日は正解です。これがインターネットの仕組みです。だからあなたはあなたの答えを編集する必要があります、それは昔々正しかったことに注意してください、そして正しい答えを参照してください。
Juuro

167

HTML5仕様の一部の抜粋:http : //w3c.github.io/html/semantics-scripting.html#element-attrdef-script-async

src属性が存在しない場合は、defer属性とasync属性を指定してはなりません。


これらの属性を使用して選択できる3つの可能なモードがあります[非同期および延期]。async属性が存在する場合、スクリプトは利用可能になるとすぐに非同期で実行されます。async属性はないがdefer属性はある場合、ページの解析が完了するとスクリプトが実行されます。どちらの属性も存在しない場合、ユーザーエージェントがページの解析を続行する前に、スクリプトがフェッチされてすぐに実行されます。


これらの属性の正確な処理の詳細は、主に歴史的な理由から、HTMLの多くの側面に関係する、いくらか重要なものです。したがって、実装要件は仕様全体に散らばっています。以下の(このセクションの)アルゴリズムは、この処理の中核を説明していますが、これらのアルゴリズムは、HTML、外部コンテンツ、およびXMLのスクリプトの開始タグと終了タグの解析ルールによって参照され、ドキュメントのルールを参照します。 ()メソッド、スクリプトの処理など


要素にsrc属性があり、要素にdefer属性があり、要素に「parser-inserted」のフラグが付けられており、要素にasync属性がない場合:

要素は、ドキュメントが要素を作成したパーサーのドキュメントに関連付けられた解析を終了したときに実行されるスクリプトのリストの最後に追加する必要があります。


37
多分、あなたの役に立たないコメントのために、ここでの私の返答は、人々が私の返答に投票するのを止めるでしょう。受け入れられた答えは間違っていません。答えは異なります。2011年の初めには、HTML5仕様は現在よりも主流のWebブラウザーに関連していなかったためです。この答えは今後より良いかもしれませんが、受け入れられた答えはどの基準でも間違っていません。
Mark At Ramp51

3
仕様の内容を知っておくと便利ですが、IE <9のようなdefer一部のブラウザーは正しく実装されてません。を使用する場合defer、一部のブラウザではスクリプトファイルが順番に実行されることに依存できません。
Flimm


最初の引用はもう有効ではありませんよね?「src属性が存在しない場合、またはスクリプトがクラシックスクリプトでない場合は、この属性を指定してはなりません。」そして、古典的なスクリプトはsrc = ""のないものです。
フェリックス・サンス

158

本当の答えは、あなたは延期を信頼できないからです。

概念上、deferとasyncは次のように異なります。

asyncを使用すると、スクリプトをブロックせずにバックグラウンドでダウンロードできます。次に、ダウンロードが完了すると、レンダリングがブロックされ、そのスクリプトが実行されます。スクリプトが実行されると、レンダリングが再開されます。

deferも同じことを行いますが、ページで指定された順序でスクリプトが実行されること、およびドキュメントの解析が完了した後にスクリプトが実行されることを保証します。そのため、一部のスクリプトはダウンロードを完了してから、後でダウンロードされてその前に表示されるスクリプトを待ちます。

残念ながら、実際には標準的なキャットファイトであるため、deferの定義は仕様ごとに異なり、最新の仕様でさえ有用な保証を提供していません。答えとして、ここ、この問題は、証明、ブラウザは延期異なっ実装します。

  • 特定の状況では、一部のブラウザーには、deferスクリプトが順不同で実行される原因となるバグがあります。
  • 一部のブラウザーDOMContentLoadedは、deferスクリプトが読み込まれるまでイベントを遅延させますが、そうでないブラウザーもあります。
  • 一部のブラウザーは、インラインコードがあり、属性がない要素に準拠しdefer、一部のブラウザーはそれを無視します。<script>src

幸い、仕様では少なくとも非同期が遅延をオーバーライドすることを指定しています。そのため、すべてのスクリプトを非同期として扱い、次のように幅広いブラウザサポートを取得できます。

<script defer async src="..."></script>

世界中で使用されているブラウザの98%と米国で99%は、このアプローチでブロックを回避します。

(ドキュメントの構文解析が完了するまで待つ必要がある場合は、イベントDOMContentLoadedイベントをリッスンするか、jQueryの便利な.ready()関数を使用してください。とにかく、これを実行deferして、まったく実装されていないブラウザーで適切にフォールバックします。)


13
ありがとう、あなたの答えは私にとって最も役に立ちました!
マーカス

5
これは間違いだと思います。deferの利点は、ページの解析が完了するまで実行されないことです。このページには、非同期と遅延の
experiments

1
@tinkerr概念的には正しい。実際には、これは真実ではありません。一貫して実装されていないため、シーケンスの保証は普遍的ではなく、保証でもありません。何かを実装するときは、実行に関心があります。デザインの意図はかわいいですが、特に役に立ちません。
Chris Moschini、2014年

2013年6月2日にリリースされたバージョン15defer以降、Operaがこの属性をサポートしていることを指摘したかっただけです。

1
@VikasBansal非同期をサポートしない古いブラウザー、つまり古いIEの場合。
Chris Moschini、2016

13

defer外部スクリプトを含める<script>ためのタグでのみ使用できます。したがって、- セクションの-タグで使用することをお勧めします。<script><head>


8

defer属性はsrcのスクリプトタグでのみ機能します。インラインスクリプトの遅延を模倣する方法を見つけました。DOMContentLoadedイベントを使用します。

<script defer src="external-script.js"></script>
<script>
document.addEventListener("DOMContentLoaded", function(event) {
    // Your inline scripts which uses methods from external-scripts.
});
</script>

これは、遅延属性スクリプトが完全にロードされた後にDOMContentLoadedイベントが発生するためです。


6

defer属性は外部スクリプト専用です(src属性が存在する場合にのみ使用してください)。



4

2013年に書かれたGoogleの開発者であるJake Archibaldによるスクリプトロードの不明瞭な水について、この優れた記事を詳しくご覧ください。

その記事の関連セクションを引用します:

延期する

<script src="//other-domain.com/1.js" defer></script>
<script src="2.js" defer></script>

Specによると:一緒にダウンロードし、DOMContentLoadedの直前に順番に実行します。「src」のないスクリプトでは「defer」を無視します。

IE <10は言う:1.jsの実行の途中で2.jsを実行するかもしれません。面白くないですか?

赤のブラウザは言う:私はこの「延期」が何であるかわからない、それがそこになかったかのようにスクリプトをロードするつもりです。

他のブラウザは言う:わかりました、しかし私は「src」なしでスクリプトの「defer」を無視しないかもしれません。

このコメントdeferよると、Firefoxの初期のバージョンでは、スクリプトの実行が完了する前にDOMContentLoadedがトリガーされることを追加します。)

最新のブラウザーはasync適切にサポートしているようですが、スクリプトが順不同で実行されていて、おそらくDOMContentLoadedの前に実行されている必要があります。


1

このブール属性は、ドキュメントが解析された後にスクリプトが実行されることをブラウザに示すために設定されます。この機能は他のすべての主要なブラウザでまだ実装されていないため、作成者はスクリプトの実行が実際に延期されると想定しないでください。据え置きスクリプトからdocument.write()を呼び出さないでください(Gecko 1.9.2以降、これによりドキュメントが吹き飛ばされます)。遅延属性は、src属性を持たないスクリプトでは使用しないでください。Gecko 1.9.2以降、src属性を持たないスクリプトでは、defer属性は無視されます。ただし、Gecko 1.9.1では、defer属性が設定されている場合、インラインスクリプトでも延期されます。

deferはchrome、firefox、つまり> 7とSafariで動作します

ref:https : //developer.mozilla.org/en-US/docs/HTML/Element/script


0

defer属性はブール属性です。

存在する場合、ページの解析が終了したときにスクリプトが実行されることを指定します。

注:defer属性は外部スクリプト専用です(src属性が存在する場合にのみ使用してください)。

注:外部スクリプトを実行するにはいくつかの方法があります。

非同期が存在する場合:スクリプトはページの残りの部分と非同期で実行されます(ページが解析を続行している間、スクリプトが実行されます)非同期が存在せず、遅延が存在する場合:ページが解析を完了したときにスクリプトが実行されますasyncもdeferも存在しない:ブラウザがページの解析を続ける前に、スクリプトがフェッチされてすぐに実行されます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.