Productivity Tips

実行タイミングを遅らせたいときに付与するdefer属性

defer属性を付与するのはなぜか

defer(ディファー)とは、HTMLの <script> タグに使う属性で、スクリプトの実行タイミングを「HTMLの解析・表示がすべて完了した後」に遅らせるためのものです。

(deferとは、英語で「延期する」「先延ばしにする」という意味。)

 

通常、<script> だけだとHTMLの読み込みは中断されて即JavaScriptが実行されますが、defer属性を付けるとHTMLのパース・DOM構築が完了してから、そのスクリプトが順次実行されます。

 

複数の <script src="..." defer> タグがある場合は、記述順に実行されます。

 

ページ表示速度を落とさずDOMContentLoaded直前に実行させたいコードに便利です。

 

DOMContentLoadedとは

HTML文書が完全に読み込まれ、構文解析(パース)が完了してDOMツリーが構築された時点で発火するJavaScriptのイベント。

簡単に言うと、「HTMLの骨組み(DOMの構造)が完成したよ!」というタイミング。

参照:Document: DOMContentLoaded イベント

 

属性値は不要で、<script src="...js" defer></script>と書くのが一般的です。

 

注意: deferは外部スクリプト専用(src属性つきのときのみ有効)です。

 

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

 

このようにすることで、スクリプトによる描画の停止を避けつつ、HTML全文をパースした上でJSを順序通り実行できるようになります。

パースとDOMで行われる処理と2つの違い

HTMLの「パース」とは、ブラウザがHTMLファイルを1文字ずつ読み取り、意味のある単位(トークン)に分解し、解釈していく処理です。

 

パース(parse)は日本語で「構文解析する」「解析する」という意味で使われます。

 

IT分野では、文字列やコードを文法や構造に従って分析し、意味のある部品(トークン)に分解する処理のことを指します。

 

そして、「DOM構築」とは、そのパース結果をもとに、HTML要素の階層構造=DOM(Document Object Model)ツリーを生成することを指します。

 

HTMLパース(解析):

HTMLパーサーがHTML文字列をトークンごと(タグ、テキスト、コメントなど)に分割し(字句解析)、そのトークンから階層構造(親子関係・入れ子)を認識していく(構文解析)。

 

これによって、HTMLコードがどのような構造を持っているかコンピュータが理解できるようになります。

DOM構築:

パースされた情報をもとに、DOMツリーという木構造のデータが作られます。

 

このツリー上の各ノード(枝)は、HTMLの各要素(<html>, <head>, <body>, など)を示し、ブラウザやJavaScriptはこのツリーを使ってページを操作・表示します。

 

例として、以下のようなHTMLがあるとすると

 

<html>
<body>
<h1>Hello</h1>
<p>World</p>
</body>
</html>

 

DOM構築後には

 

最上位に「Documentノード」

その下に「html」ノード、

さらにその子が「body」ノード

さらに「h1」「p」などが階層的につながる

 

という木になり、これがWebページの構造の“本体”となります。

 

この一連のパースとDOM構築により、HTML文書はブラウザで表示され、同時にJavaScriptなどによる動的な操作の対象にもなります。

-Productivity Tips