Javascriptの読み込み、WordPressでasync/deferをつける方法

1. Javascript を非同期で読み込む。async 属性と defer 属性

非同期で読み込むというのは、HTML が上から順に読み込んでいく間に並行して読み込みをしてくれるので、ページの読み込みが早くなるメリットがあります。async 属性と defer 属性どちらも src 属性で読み込まれたものじゃないと効果がありません。(インラインでは使用不可)

async 属性

読み込みが完了した時点で実行されるので読み込み順が関係あるようなファイルには向かず、独立したアクセス解析や SNS のページプラグインなどと相性が良い

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

defer 属性

HTML が解析された時点で実行される。(DOMContentLoaded が発生する前に実行)defer 属性を持ったファイルが複数ある場合は上から順に実行される。

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

2. DOMContentLoaded と window.onload

async 属性と defer 属性はファイルをどう読み込むか指定するものですが、下記は Javascript 内で読み込み方を指定する方法です。

DOMContentLoaded

HTML が解析されたときに処理を実行。

window.addEventListener("DOMContentLoaded", () => {
  console.log("読み込まれました(DOMCon)")
})

window.onload

ページ内のすべて(画像など)の読み込みが完了したときに処理を実行するので、DOMContentLoaded より実行が後になる。

window.onload = function () {
  console.log("読み込まれました(onload)")
}

3. WordPress で async 属性と defer 属性をつける場合

WordPress で async 属性や defer 属性をつける場合は、下記のように記述するとつけられますが、プラグインとの相性や環境によっては不具合が生じるかもしれません。私の場合、if(!is_admin()) {...}(管理画面には適用しない)をつけなかったとき、投稿画面関係で使用しているプラグインが動作しなくなったりしました。

//functions.php

//deferを追加
if(!is_admin()) {
  function add_defer($tag, $handle) {
    if($handle === 'script') {
      return str_replace(' src=', ' defer src=', $tag);
    }
  }
  add_filter('script_loader_tag', 'add_defer', 10, 2);
}

//asyncを追加
if(!is_admin()) {
  function add_async($tag, $handle) {
    if($handle === 'script') {
      return str_replace(' src=', ' async src=', $tag);
    }
  }
  add_filter('script_loader_tag', 'add_async', 10, 2);
}

if(!is_admin()) {...} - 管理画面を除く
str_replace - 文字列の置換え
script_loader_tag - スクリプトタグのフィルターフック
if($handle === 'xxxx') {...} - $handle と xxxx が等しい場合...
xxxx には、wp_enqueue_scriptの第一引数が入ります。下記でいうと、'script'の部分

wp_enqueue_script('script', get_template_directory_uri() .'/js/script.js');

script_loader_tag | Hook | WordPress Developer Resources