- 位置が重要
- asyncとdefer
- deferまたはasyncなし。 in the head
- Defer or asyncなし、in the body
- With async, in the head
- With defer.In the body
- Defer.In the body
- With async, in the head
- Blocking parsing
- Blocking rendering
- domInteractive
- Just tell me the best way
パフォーマンス比較
Keeping things in order
HTML ページでスクリプトを読み込むとき、ページの読み込み性能を損ねないよう注意しなければならない。
スクリプトは伝統的にこの方法でページに含まれます:
<script src="https://flaviocopes.com/javascript-async-defer/script.js"></script>
HTML パーサーがこのラインを見つけるといつでも、スクリプトを取得するリクエストが作られ、そのスクリプトが実行されます。
この処理が完了すると、解析が再開され、残りの HTML を解析できます。
想像できるように、この操作はページの読み込み時間に大きな影響を与えることがあります。
たとえば、ネットワークが少し遅い場合やモバイル デバイスで接続状態が少し不安定な場合、予想よりも読み込みに少し時間がかかると、訪問者にはスクリプトが読み込まれて実行されるまで空のページが見えることが多いでしょう。
位置の問題
初めて HTML を学ぶとき、script タグは <head>
タグ内にあると教わりました:
<html> <head> <title>Title</title> <script src="https://flaviocopes.com/javascript-async-defer/script.js"></script> </head> <body> ... </body></html>
先にお話したように、パーサーがこのラインを見つけると、スクリプトを取り出してそれを実行しに行くのです。 そして、このタスクが完了した後、body の解析に進みます。
これは、多くの遅延が発生するため、よくありません。 この問題に対する非常に一般的な解決策は、script
タグをページの一番下、閉じる </body>
タグの直前に置くことです。
こうすることにより、すべてのページがすでに解析され読み込まれた後にスクリプトが読み込まれて実行されるので、head
代替方法よりも大幅に改善されます。 async
と defer
です。
Async and Defer
async と defer は両方ともブール値の属性です。
<script async src="https://flaviocopes.com/javascript-async-defer/script.js"></script>
<script defer src="https://flaviocopes.com/javascript-async-defer/script.js"></script>
両方を指定すると、モダンブラウザでは async
が優先され、defer
をサポートしているが async
はサポートしていない古いブラウザでは defer
にフォールバックします。
これらの属性は、ページのhead
部分でスクリプトを使用する場合にのみ意味があり、上で見たようにbody
フッターにスクリプトを置いた場合は意味がありません。
パフォーマンス比較
defair や async なし、ヘッド
以下は、ページの head
部分に置かれた defer や async なしのスクリプトをページが読み込む方法です:
The parsing is pause until script is fetched and executed. これが完了すると、解析が再開されます。
No defer or async, in the body
How the page loads a script without defer or async, put at the end of the body
tag, just before it closed:
The parsing is done without any pause, and when it ends, the script is fetched, and execached. 解析はスクリプトがダウンロードされる前に行われるため、ページは前の例よりずっと前にユーザーに表示されます。
With async, in the head
以下は、head
タグ内に置かれた async
でページがスクリプトを読み込む方法です:
スクリプトは非同期に取得され、準備ができたら HTML パースを一時停止し、その後に再開される。
With defer, in the head
Here’s how a page loads a script with defer
, put in the head
tag:
The script is fetched asynchronously, and it’s executed only after the HTML parsing is done.これは非同期に取得されるスクリプトの実行を停止して HTML 解析を行った後、スクリプトを再開します。
パース処理は、body
タグの最後にスクリプトを置いたときと同様に終了しますが、スクリプトは HTML パース処理と並行してダウンロードされているため、全体としてスクリプトの実行はかなり前に終了しています。
つまり、これは速度の点で勝利するソリューションです。
Blocking parsing
async
はページのパースをブロックし、defer
はしません。 これは、あなたとあなたのスクリプト次第です (たとえば、スクリプトが onLoad
イベントの後に実行されるようにします)。
domInteractive
defer
のマークが付いたスクリプトは domInteractive
イベントのすぐ後で実行されますが、これは HTML が読み込まれて解析され DOM を構築した後に発生するイベントです。
CSS および画像は、この時点ではまだ解析および読み込み中です。
これが完了すると、ブラウザは domComplete
イベントを発行し、onLoad
となります。
domInteractive
はそのタイミングが読み込み速度を認識させるものとして重要視されています。 詳細は MDN を参照してください。
順番を守る
もうひとつのケース pro defer
: async
とマークされたスクリプトは、利用可能になると、カジュアルな順番で実行されます。 defer
とマークされたスクリプトは、マークアップで定義された順序で (パースが完了した後に) 実行されます。
ベストな方法を教えてください
スクリプトを使用しているときにページの読み込みを高速化するために行う最善の方法は、それらを head
に配置し、defer
属性を script
タグに追加することです:
<script defer src="https://flaviocopes.com/javascript-async-defer/script.js"></script>
これは、高速な domInteractive
イベントのトリガーであるシナリオです。
defer
の長所を考慮すると、さまざまなシナリオで async
よりも良い選択と思われます。
ページの最初のレンダリングを遅らせることに問題がなければ、ページがパースされるときに、実行したい JavaScript がすでに実行されていることを確認します。
Download my free JavaScript Beginner’s Handbook
More browser tutorials:
- HTML5 で利用できる便利なトリック
- How I made a CMS-?
- The Complete Guide to Progressive Web Apps
- The Fetch API
- The Channel Messaging API
- Service Workers Tutorial
- The Cache API Guide
- The Notification API Guide
- Dive into IndexedDB
- The Selectors API.NET Framework
- Service Workers Tutorial
- Cache API Guide
- Efficient load JavaScript with defer and async
- The Document Object Model (DOM)
- The Web Storage API: The Web Storage API: ローカル ストレージとセッション ストレージ
- HTTP Cookie の仕組み
- History API
- WebP Image Format
- XMLHttpRequest (XHR)
- An-depth SVG tutorial
- データ URL とは
- Webプラットフォームを学ぶためのロードマップ
- CORS.Data URL
- Logicools API
- Web Workers
- The requestAnimationFrame() guide
- What is Doctype
- Working with DevTools Console と Console API
- The Speech Synthesis API
- How to wait for DOM ready event in plain JavaScript
- How to add a class to a DOM 要素
- querySelectorAll から DOM 要素をループする方法
- DOM 要素からクラスを削除する方法
- DOM 要素がクラスを持っているかどうかを確認する方法
- DOM ノードの値を変更する方法
- querySelectorAll から返ってきたDOM要素のリストにクリックイベントを付加する方法
- WebRTC, Real Time Web API
- JavaScript で要素のスクロール位置を取得する方法
- DOM 要素を置換する方法
- 入力ファイルフィールドで画像のみを受け付ける方法
- なぜブラウザのプレビューバージョンを使用するのか?
- The Blob Object
- The File Object
- The FileReader Object
- The FileList Object
- ArrayBuffer
- ArrayBufferView
- The URL Object
- Typed Arrays
- The DataView Object
- The BroadcastChannel API
- The Streams API
- The FormData Object
- The Navigator Object
- ジオロケーションAPIの使い方
- Drag and Drop API の使い方
- Web ページでスクロールを扱う方法
- JavaScript でフォームを処理する
- キーボードイベント
- Mouse イベント
- タッチイベント
- DOM 要素からすべての子を削除する方法
- vanilla Javascript を使用して HTML 属性を作成する方法
- JavaScript でチェックボックスにチェックが入っているかを確認する方法
- JavaScriptでクリップボードにコピーする方法
- JavaScriptでボタンを無効にする方法
- ブラウザでページを編集可能にする方法
- How to make a page editable in the browser? URLSearchParamsを使ってJavaScriptでクエリ文字列の値を取得する方法
- ページからすべてのCSSを一度に削除する方法
- insertAdjacentHTMLの使用方法
- Safari.NETを使用する方法
- Safari.NETを使用する方法
- Safari, 終了する前に警告する
- JavaScript を使用して DOM に画像を追加する方法
- How to reset a form
- How to use the Google Fonts
The Push API Guide
Notification API guide インデックスデータベース。 querySelector と querySelectorAll
Webプラットフォームとは? クロスOrigin Resource Sharing
getUserMedia() の使い方
チェックボックスはどのように使用しますか?