質問: **やりたいこと** * 目的1.ページ読み込み完了前に実行する(jQueryやグローバルナビゲーションなど)js読込 * 目的2.ページ読み込み完了後に実行する(クリックしたら一番上までスクロールなど)js読込 --- **Q.下記組み合わせがあると思うのですが、やりたいことをそれぞれ実現するためにはどうすれば良いですか?** 目的に応じて、それぞれ2つに分け、js読込を記述しようと考えています。 記述場所 ・``タグ直前 ・``タグ直前 記述方式 ・`
回答: async, deferは利用時の制約がありますので、それに応じてどの順序でどこに記述するかある程度決定されます。 これらのオプションを利用する場合、JavaScriptによるブラウザのFirst Paintのブロックを回避するために利用します。 ただし、これらは正しく利用しないと機能要件を満たせない場合があるので、順を追って指定していきましょう。 Step 1: bodyの最後でscriptを記述する まずは機能要件を確実に担保するには、``の直前に` ``` まずはこの形式を作ってください。 Step 2: deferをつける HTMLパーサーがscriptの記述箇所に到達したあと、JavaScriptのダウンロードが始まり、 HTMLのパースが完了してから実行されます。つまり、`script`タグを`head`タグ内に記述すると`body`末尾につけるより早くJSのダウンロードが完了します。また、`defer`は定義された**順番に実行**されます。 これらより、Step 1のコードは次のように書き換えることができます。 ``` ``` Step 3: asyncをつける `async`を付与可能なscriptタグには条件があります。 * 読み込むJavaScriptが他のコードに依存していない場合 * 機能的に先に読み込まれても問題ない場合 たとえば次のようなケースを考えます。 * `jquery.js`: jQueryライブラリ * `file1.js`: 実装にjQueryを利用している * `file2.js`: 実装にjQueryを利用していない このとき、`file1.js`は`jquery.js`に依存しているため`jquery.js`の読み込み後に実行する必要があります。 すなわち、以下のように書くことができます。 ``` ``` `file2.js`は排他的なコードであるため、`file1.js`や`jquery.js`よりも前に実行しても良い気がしますが、 `file2.js`がダウンロード完了後にJavaScriptが即実行され、その間HTMLのパースが一時停止されます。仮にパースが再開されるまでの待機時間が長く、その後に`defer`の付いたscriptタグがパースされ、後者のダウンロード時間がHTMLパース完了より長い場合に時間的な損失が発生します(追記画像のPattern 2に該当します)。 すなわち、`defer`のあとに`async`のついたscriptタグを定義したほうが細かい損失を気にせずに済みます。 回答 今回の問に対する回答に移ります。 > > * 目的1.ページ読み込み完了前に実行する(jQueryやグローバルナビゲーションなど)js読込 > * 目的2.ページ読み込み完了後に実行する(クリックしたら一番上までスクロールなど)js読込 > > > これだけの条件であれば、Step 2の`defer`オプションをつけた`script`タグを`head`タグ末尾に入れる、までとなります。`async`オプションを付けるかどうかを判断するためには、ファイルの実行順序の依存関係の情報が必要です。 追記 !async, deferをつけたscriptがタグの動き