零弐壱蜂

[WordPress] script要素にdefer/asyncを付与する方法

2 min read

functions.phpにコードを追加して<script>タグにdefer/async属性を付与する。

defer/asyncとは

async属性

ダウンロード完了直後、レンダリングとスクリプトを平行して実行する。

defer属性

ページの解析後、レンダリングとスクリプトを平行して実行する。 ただし、スクリプトはレンダリング完了後に実行する。

注意

実行順序が保証されなくなるため、ライブラリなどにasync・deferは指定しない方がよい。 また、document.write()などのレンダリング関連の処理があると使えない。


functions.php に追加するコード

clean_url

function add_attr_for_script($url) {
  return ( strpos($url, '.js' ) === false ) ? $url : $url ."' defer='defer' async='async";
}
add_filter('clean_url', 'add_attr_for_script', 11, 1);

一括で付与するので用法を守って正しくお使いください。


ライブラリを読み込んでる場合はこういう条件も入れた方がよいかも。

if ( strstr($url, 'jquery') !== false ) {}

script_loader_tag

たいていの場合、以下のような形でスクリプトを出力用のキューに入れて出力していると思う。

wp_enqueue_script('js', get_template_directory_uri(). "hoge.js", [], null, true);

ここでは、スクリプトのハンドル名を指定を「js」としているが任意で付けて良い。この名称を後述の処理で使用する。

function add_async_to_script( $tag, $handle ) {
  if ( 'js' !== $handle ) { // wp_enqueue_scriptに指定したハンドル名'js'
    return $tag;
  }
  return str_replace( ' src', ' async="async" src', $tag );
}
add_filter( 'script_loader_tag', 'add_async_to_script', 10, 2 );

ifの条件は!==でも===でもどちらでも良いが、やっていることはclean_urlと大差ない。