JavaScriptとは②

2023/03/09に公開

MDN( https://developer.mozilla.org/ja/docs/Web/JavaScript
を参考に勉強するように注意が入ったので、こらを教本にしていきます。
その為、抜粋しながら進めたいと思います。
今回はこちらのページです。

スクリプトの読み込み方針

スクリプト[1]を適切なタイミングで読み込むためには、いくつかの問題があります。
一般的な問題は、ページ上のすべてのHTMLが、現れた順に読み込まれることです。
そのためJavaScriptを使用してページ上の要素を操作する場合、HTMLよりも前にJavaScriptが読み込まれて解釈されても、コードは動作しません。

前回の内部の例と外部の例では、HTML本文が解釈される前にJavaScriptが読み込まれて文書のheadで実行されています。 これによりエラーが発生する可能性があるため、いくつかの構文を使用して回避しています。

内部の例では、こちら。(estelleさん作成)

document.addEventListener('DOMContentLoaded', () => {
・・・
});

これはブラウザーのDOMContentLoadedイベントを待ち受けするイベントリスナーで、 HTMLの本体が完全に読み込まれて解釈されたことを示します。このブロック内のJavaScriptは、そのイベントが発生するまで実行されないため、エラーは回避されます。

DOMContentLoaded

Document Object Model(=DOM、ドキュメントオブジェクトモデル)はHTML や XML 文書を取り扱うためのAPI。
『DOMContentLoaded』イベントはDOMの読み込みと解析が完了してから起動し、画像やCSS、JavaScriptの読み込みが完了するのを待たないで行われる。

外部の例(html.js)では、こちら。(estelleさん作成)

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

より現代的な JavaScript機能のdefer属性を使用して問題を解決し、
<script> 要素[2]になった後もHTMLコンテンツのダウンロードを続行するようブラウザーに指示。
この場合、スクリプトとHTMLの両方が同時に読み込まれ、コードが機能します。

この問題に対する昔ながらの解決策は、すべての HTML が解釈された後に読み込まれるように、 body の下部に(たとえば </body> タグの直前に) script 要素を置くことでした。 この解決の問題点は、HTML DOM が読み込まれるまでスクリプトの読み込みと解釈が完全にブロックされることです。
JavaScript がたくさんある大規模なサイトでは、これは大きなパフォーマンス上の問題を引き起こす可能性があり、サイトを遅くします。

async(エイシンク)とdefer(デファー)

実際には、スクリプトのブロッキングの問題を回避できる現代的な機能が2つあります。『async』 と 『defer』です。
これらの2つの違いを見てみましょう。

async, deferをつけない場合

  • HTML Parser中にscriptタグが見つかる。
    HTML Parserを中断
    →scriptをダウンロードする。
    →scriptを実行する。
    →HTML Parserを再開する

async属性

  • ページをブロックすることなくスクリプトをダウンロードする。 ダウンロードが完了すると、スクリプトが実行され、ページのレンダリング[3]がブロックされる。
  • 複数のスクリプトが特定の順序で実行されるという保証はない。
  • ページ内のスクリプトが互いに独立して実行され、ページ内の他のスクリプトに依存しない場合は、 asyncを使用するのが最もよい方法。

たとえば、次のスクリプト要素があるとします。

<script async src="js/vendor/jquery.js"></script>

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

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

スクリプトが読み込まれる順序に頼ることはできません。
jquery.js が読み込まれるのは script2.js と script3.js よりも前かもしれませんし、後かもしれません。
この場合、これらのスクリプトの関数が jquery に依存していると、スクリプトの実行時に jquery が定義されないため、エラーが発生します。
読み込むバックグラウンドスクリプトがいくつもあって、それらをできるだけ早く実行したい場合にasyncを使用。

  • HTML Parser中にscriptタグが見つかる。
    scriptはダウンロードされる。HTML Parserは継続。
    →scriptのダウンロードが完了。
    →HTML Parserを中断する。
    →scriptを実行する。
    →HTML Parserを再開する。

defer属性

  • defer属性で読み込まれたスクリプトは、ページに表示されている順番に読み込まれる。
  • ページのコンテンツがすべて読み込まれるまで実行されない。
  • スクリプトがDOMに依存している場合に便利。

たとえば、次のスクリプト要素があるとします。

<script defer src="js/vendor/jquery.js"></script>

<script defer src="js/script2.js"></script>

<script defer src="js/script3.js"></script>

ページに現れた順序でスクリプトを実行し、スクリプトとコンテンツが読み込まれるとすぐにスクリプトを実行します。
defer属性を持つすべてのスクリプトは、ページに現れた順序で読み込まれます。
したがって、jquery.js → script2.js → script3.js の順に読み込まれることは確実です。
ページコンテンツがすべて読み込まれるまでは、実行せず、これはスクリプトがDOM配置に依存している場合に便利です(例: ページの要素を変更する場合)。

  • HTML Parser中に scriptが見つかる。
    scriptがダウンロードされる。HTML Parserは継続。
    →scriptのダウンロードが完了。HTMLパーサーは継続。
    →HTML Parserが完了。
    →scriptを実行する。
脚注
  1. スクリプト(script)とはプログラムの種類の一つで、人間が読み書きしやすいプログラミング言語で書かれたプログラム(ソースコード)を簡単に解釈実行できるようにした、簡易なコンピュータプログラムのことです。
    ※ソフトウェアの設計など、コンピュータに命令を与える際には、通常、人間が普通に読み書きできる言語から、コンピュータが理解できる言語、いわゆる機械語への変換が必要です。 ↩︎

  2. script要素は、JavaScriptの埋め込みを表し、ブラウザ上には表示されません。外部JavaScriptファイルを読み込んだり、ページに直接JavaScriptを記述する場合に使用します。 ↩︎

  3. レンダリング(rendering)とは、あるデータを処理または演算することで画像や映像を表示させることです。 動画制作などにおいては、さまざまな形式のデータに処理を加えることによって、映像や画像や音声などを生成する作業を指します。 ↩︎

Discussion