質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

92.00%

  • JavaScript

    8349questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

  • HTML

    4678questions

    HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

  • jQuery

    3727questions

    jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

jQueryやJSライブラリ等をbodyタグで読み込むことによるデメリットってあるんでしょうか?

解決済

回答 3

投稿 2015/08/16 19:30

  • 評価
  • クリップ 4
  • VIEW 9,253

opoonabst

score 237

JSファイルはBodyタグの最後に読み込んだ方が何かとメリットがあるというのはよく聞きますが、
bodyタグ最後とheadタグのどっちでjQueryCDN読み込んでいるのか調べると普通にheadタグ内で読み込んでるサイトの方が多いように感じます。

そこで質問なのですが、逆にBodyタグ最後でJSファイルを読み込むことによるデメリットってあるんでしょうか?
  • 気になる質問をクリップする

    クリップした質問に回答があった場合に通知・メールを受け取ることができます。

    クリップした質問はマイページの「クリップ」タブからいつでも見ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

+6

  <script src="hoge.js"></script>
</head>
<body>
  <p>It is a test.</p>
</body>
</html>

上記 HTML では hoge.js が読み込み終わって hoge.js 内のスクリプトコードが実行されるまで </head> 以降のHTML(It is a test)のレンダリングが停止します。

</head>
<body>
  <p>It is a test.</p>
  <script src="hoge.js"></script>
</body>
</html>

上記 HTML ではbody要素内の HTML(It is a test.) のレンダリングが終わってから hoge.js の読み込みを始める為、レンダリングの停止が発生しません。

</body> 直前に <script> を置くのはscript読み込み中のレンダリング停止をなくすのが目的であり、メリットです。
逆にレンダリング前にJavaScriptを実行させたければ <head> に置きますが、そうでなければ、</body> 直前に <script> を置くのがレンダリングの高速化に繋がるのでお勧めです。
副次的効果ですが、</body> 直前に置けば DOMContentLoaded を待つコードを省略出来ます。

投稿 2015/08/17 14:21

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    以下のような回答は評価を下げられます

    • 間違っている回答
    • 質問の回答になっていない投稿
    • 不快な投稿

    評価を下げる際はその理由をコメントに書き込んでください。

checkベストアンサー

+1

think49様が書かれている通り、bodyの閉じタグ直前にscriptタグを書いたほうが良いと言われていた理由はHTMLやCSSの読み込み・レンダリングをブロックしないという所です。

だだ、HTML5でサポートされたasync属性をつければHTMLやCSSのレンダリングをブロックせずにjavascriptを読み込むこともできますので、heahタグ内に書いても問題無くなってきています。
ex
<head>
  <script src="/maim.js" async></script>
</head>

ただ、このasync属性は注意が必要で複数スクリプトがあった場合読み込まれる順番が担保されません。
具体的に言えば、jQueryと自分で作ったjQuery使用したjavascriptmain.jsを別ファイルで読み込ませる場合などは先にjQueryが読み込まれる担保ができませんので、予期しないエラーを発生させる可能性ができてしまいます。
<head>
  <script src="/jQuery" async></script> <!-- jQuery が先に読み込まれるとは限らない! -->
  <script src="/maim.js" async></script>
</head>
このような使い方であれば、asyncを使わずに、bodyの閉じタグ前に書いてあげる方が読み込み順も担保できるので確実です
  <script src="/jQuery"></script> <!-- jQuery が先に読み込まれる -->
  <script src="/maim.js"></script>
</body>

ですので、使用するjQueryなどのライブラリも1つのファイルにまとめる。もしくは、他のjavascriptファイルに依存しないファイルであればasync属性を使えばhead内に記述しても、レンダリングをブロックしてしまうということはありません。

[参考]
async属性で簡単!非同期でjsを読み込みレンダリングを速くしよう


[追記]
逆にBodyタグ最後でJSファイルを読み込むことによるデメリットってあるんでしょうか?
HTMLのレンダリングが完了する前に何かjsを動かしておきたいというような事があれば、bodyの閉じタグ前より先にスクリプトタグを書いておかなければ意図したとおり動作しないかと思います。

下の例ではwriteImage.jsのある位置にもともとあったかのようにimgタグが追加されます。
HTMLがレンダリングされてから画像1の前にjavascriptで画像を追加すると一瞬表示がガタッとなってしまうかもしれません。これが嫌だ!というような場合はHTMLのレンダリングをブロックさせてでもスクリプトを実行させるメリットは有るかもしれません。
<body>
<script src="writeImage.js"></script>
<div>
  <img alt="画像1" src="http://dic.nicovideo.jp/oekaki/663056.png">
</div>
</body>
// writeImage.js
var d = document;
var url = 'http://cdn-ak.b.st-hatena.com/entryimage/236933222-origin-1419307828.jpg';
var img = d.createElement('img');
img.src = url;
d.getElementsByTagName('body').item(0).appendChild(img);
メリットとは別の先に書いていたasyncとの違いも試してみるとこが出来ます。
<script src="writeImage.js" async></script>としてみてください。
asyncはHTMLのレンダリングをブロックしませんので、必ずしも追加される画像が画像1の上に表示される訳ではなくなる事が確かめられると思います。


最近のTwitterとかはてなとかの埋め込みscriptタグはasync付きのものが多いですが、
コメントでご指摘頂いております通り、asyncの方法は下記に注意する必要があります。
“async”(非同期)はIE 8/9, Android 2.2/2.3.といった、いくつかの前の型のブラウザに対応していません。

[参考]
JavaScriptの読み込みにおける非同期スクリプト注入の悪影響

投稿 2015/08/18 13:59

編集 2015/08/18 16:05

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    以下のような回答は評価を下げられます

    • 間違っている回答
    • 質問の回答になっていない投稿
    • 不快な投稿

    評価を下げる際はその理由をコメントに書き込んでください。

  • 2015/08/18 15:10 編集

    script[async] は IE9- が未サポートである点に注意が必要だと思います。
    http://caniuse.com/#feat=script-async
    MSのサポートサイクル的には下記スケジュールとなるので、2017/04/10 まで script[async] が使えないブラウザがある事を考慮する必要があります。
    - 2016/01/12 … IE7+ (Windows Vista SP2 の最下位ver)
    - 2016/01/13 … IE9+ (Windows Vista SP2 の最上位ver / ポリシー変更で最上位版だけサポート対象に)
    - 2017/04/11 … IE11+ (Windows Vista SP2 の延長サポート終了日)

    > d.getElementsByTagName('body').item(0).appendChild(img);
    問題の大本は appendChild にあるので、DOMContentLoaded まで待ってから insertBefore すれば script[async] を使っても期待通りに動作すると思います。

    キャンセル

  • 2015/08/18 15:31 編集

    think49さま
    確かにIE系のサポートは度外視していた回答になっていたかと思います。
    IE9が3.9%ほどのシェア率なのでまぁどこまでサポートするのか?という問題でもあるかと思いますが、サポートできる範囲を多く取ろうと思えば必要ですね。

    追記したサンプルの件は、asyncが無ければブロックするから、スクリプトタグのある位置にはいるよ。asyncをつけると必ずしもそこに入るとは限らないよ。(担保できないよ)という事で、bodyの閉じタグ直前に書かない事でできるような雑いサンプルになりますので、意図させた場所に画像を入れたいという意味合いのものではありません。
    意図させた場所に画像を入れる方法はいくらでもありますし。

    `d.getElementsByTagName('body').item(0).appendChild(img);` と書いてあるのはasyncとした場合にdocument.writeが無視されるので、本当はdocument.writeで書いたほうが解りやすいのですが、jsの処理が変わると比較しづらいかと思いこう書いたのですが意図が伝わりにくい書き方になっていたようで申し訳ないです。

    JavaScriptの読み込みにおける非同期スクリプト注入の悪影響
    http://postd.cc/script-injected-async-scripts-considered-harmful/

    キャンセル

  • 2015/08/18 15:38

    「コード製作者の意図は scriptElement.nextSibling に img 要素ノードを挿入する動作だが、期待に反して img 要素ノードが挿入される場所が不定」を伝えたかったのだと推察します。
    ただ、この書き方では「非同期処理では上手くいかないから同期処理を使ってね」と読めなくもないので、非同期処理としての書き方(解決法)を示唆する一文が合ってもいいのではと思いました。

    キャンセル

  • 2015/08/18 15:57

    think49さま
    コメントありがとうございます。
    scriptタグがHTMLの読み込みをブロックして動作するよ、というのが解りやすいかなと思いサンプルコードを書かせていただきました。これは質問者様の
    > 逆にBodyタグ最後でJSファイルを読み込むことによるデメリットってあるんでしょうか?
    に対して、良い悪いは別としてブロックさせる事でこんなこともできなくはないですよ。という事を示したかったのですが、自分の回答した`async`の問題も合わせて説明してしまったために、齟齬を与える事になり申し訳ないです。

    キャンセル

0

jQuery等、HTMLに直接スクリプトを埋め込んだ時に利用したいライブラリは、埋め込んだJavaScriptが読み込まれる前にロードが終わってないと、HTMLに埋め込んだスクリプトが動かなくなります。このスクリプトが動かないと、表示が想定したとおりにできません。なので、jQuery等はheadタグで読み込んでいる事が多いです。

参考: 外部CSSと外部JavaScriptで表示速度の低下を防ぐには

投稿 2015/08/16 19:36

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    以下のような回答は評価を下げられます

    • 間違っている回答
    • 質問の回答になっていない投稿
    • 不快な投稿

    評価を下げる際はその理由をコメントに書き込んでください。

15分調べてもわからないことは、teratailで質問しよう!

ただいまの回答率

92.00%

関連した質問

同じタグがついた質問を見る

  • JavaScript

    8349questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

  • HTML

    4678questions

    HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

  • jQuery

    3727questions

    jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

閲覧数の多いJavaScriptの質問