JavaScriptの実行タイミングについて

JavaScriptが実行されるタイミングとしては、大きく分けて以下の4種類あります。

  1. 直ぐに実行
  2. DOMの読み込み完了後(DOMContentLoaded)
  3. CSSや画像など、ページで使用しているリソースを全て読み込んだ後(load)
  4. ユーザーが特定の操作をした後(click, scroll, resize など)

今回は上記のうち、ユーザーが操作したタイミング以外の3点について試してみたいと思います。

今回試す内容に関して、特に補足のない限りhead内で記述している点ご注意ください。

直ぐに実行

通常記述をした場合、そのコードは直ぐに実行されます。
以下の場合、ユーザーエージェントの情報をconsoleに表示します。

const ua = navigator.userAgent.toLowerCase();
console.log(ua);

直ぐに実行するデモページ

上記のような場合は問題ないですが、例えばDOM要素に対して操作などを行おうとした場合、DOM要素より前に記述があると操作ができません。

document.getElementById('header').style.color = 'red';
<header id="header">ヘッダー</header>

DOM要素の前にJavaScriptの記述がある場合のデモページ

DOM要素の後に記述がある場合は操作できます。

<header id="header">ヘッダー</header>
<script>
document.getElementById('header').style.color = 'red';
</script>

DOM要素の後にJavaScriptの記述がある場合のデモページ

DOMContentLoaded

次にDOMContentLoadedですが、DOMの読み込み完了後に実行されます。
直ぐに実行する例だとhead内に記述した場合操作ができませんでしたが、DOMContentLoadedを使用した場合はDOMの読み込み完了後に実行されることになるので操作できます。

document.addEventListener('DOMContentLoaded', function() {
  document.getElementById('header').style.color = 'red';
});
<header id="header">ヘッダー</header>

DOMContentLoadedのデモページ

後述するloadとの違いとしては、loadは外部リソースも含めて読み込み完了した後に実行される点です。
例えば画像のサイズを取得して何らかの処理を行おうとした場合、DOMContentLoadedだと外部リソースが読み込まれているかはわからないので、サイズを取得できない場合があります。

document.addEventListener('DOMContentLoaded', function() {
  const imgW = document.getElementById('img').naturalWidth;
  console.log(imgW);
});
<img src="../img.jpg" id="img">

ページアクセスが2回目以降だと画像のキャッシュが残るため、サイズ取得ができやすいので注意が必要です。
DOMContentLoadedで画像サイズを取得した場合のデモページ

load

loadは前で記載したように、ページで使用しているリソースを全て読み込んだ後に実行されます。
前述の画像サイズを取得する例の場合、loadを使用すると問題なく取得できます。

window.addEventListener('load', function() {
  const imgW = document.getElementById('img').naturalWidth;
  console.log(imgW);
});

loadのデモページ

loadを使用する方法としては addEventListener() ではなくwindow.onload = function() {〜}; といった書き方もありますが、この場合は複数あると後述の内容で上書きされてしまうため、 addEventListener() を使用する方がよさそうです。

window.addEventListener('load', function() {
  console.log('addEventListener 1回目');
});
window.addEventListener('load', function() {
  console.log('addEventListener 2回目');
});
window.onload = function() {
  console.log('window.onload 1回目'); // 2回目に上書きされて実行されない
};
window.onload = function() {
  console.log('window.onload 2回目');
};

window.onload が上書きされる場合のデモページ

まとめ

今まで試した内容だとloadを使用するのが無難な感じになりますが、実行タイミングとしては、(1)直ぐに実行、(2)DOMContentLoaded、(3)load の順番になります。

window.addEventListener('load', function() {
  console.log('load'); // 3番目
});
document.addEventListener('DOMContentLoaded', function() {
  console.log('DOMContentLoaded'); // 2番目
});
console.log('直ぐに実行'); // 1番目

実行順のデモページ

例えばページのローディングを非表示にするタイミングであればloadで全てのリソース読み込み後になると思いますが、リソースの関わらないDOMの操作などであればDOMContentLoadedのタイミングで実行した方が早く処理が実行できますし、最初に試したユーザーエージェントの取得などであれば直ぐに実行しておいた方がよい場合が多いです。
このように、処理内容に応じてそれぞれを使い分けられるようにできるとよいのかなと思います。

参考サイト

このエントリーをはてなブックマークに追加

関連記事

コメントを残す

メールアドレスが公開されることはありません。
* が付いている欄は必須項目です

CAPTCHA


コメントが承認されるまで時間がかかります。

2024年10月
 12345
6789101112
13141516171819
20212223242526
2728293031