https://idea-hack.com/blog/107045/

WordPressでレンダリングを妨げるリソースの除外を行う方法

WordPressでレンダリングを妨げるリソースの除外を行う方法を紹介しています。適切に作業を行えば、Google Page Speed Insightの評価を大幅向上できます。

レンダリングを妨げるリソースとは?

WordPressは特性上複数の開発者による複数のプラグインやテーマを動かすことがざらにあります。

30のプラグインを動かしていたとして、30のプラグインの作者が全て別の人なんてことも珍しくありません。

そうなると、サイトの読み込み時ファイルの総数は100を超えることもあります。

仮に100回ファイルを読み込むということは、100回サーバーに対してリクエストを投げることになります。その全てが完了するまでWEBページの読み込みは完了したと見なされません。

この100回のリクエストで取得されるリソースは、その都度サイトの表示(レンダリング)を妨げるので「レンダリングを妨げるリソース」と呼ばれます。

これを放置すると、Google Page Speed Insightの評価が落ち、ページ読み込み速度にも影響が出ますので、改善したいところです。

レンダリングを妨げるCSSリソースを除外する

CSSの場合、メインのCSSをインラインで記述し、外部CSSファイルは全て遅延読み込みさせるのが効果的です。

しかし、不特定多数の開発者のコードが混在するWordPressサイトの場合、全てのCSSを非同期処理させる時には、以下を前提としておく必要があります。

  • CSSの読み込み順はいじるべきではない
  • CSSの読み込み位置をいじるべきではない
  • 複数のCSSファイルをひとまとめにしてリクエスト数を減らす施策をとるべきではない。

全て自分のコードでサイトが構築されている場合、これらの前提を無視しても問題ないケースがあります。そうだとしても、あなたが高度な知識を持ったWordPress開発者でもない限りは、これらの前提を守るべきです。

それでは、作業を始めましょう。

メインのファイルをインラインに記述させる

お使いのテーマが自作ではない場合は、実際に適用するのは難しいかもしれませんが、この手法で開発を進めれば、重要なCSSファイルをインラインに記載することが可能です。

今回はBootstrap4をインラインで読み込みます。

WordPressでCSSファイルを取得してインラインスタイルとして出力する方法WordPressでCSSファイルを取得してインラインスタイルとして出力することで、Google Page Speed Insightのスコア向上が期待できます。
Step 1
CSSを圧縮する関数を用意
PHP
<?php
compress_kirki_css_code( $code ) {
		// Remove Comments
		$code = preg_replace( '!/*[^*]**+([^/][^*]**+)*/!', '', $code );
		// Remove tabs, spaces, newlines, etc.
		$code = str_replace( array( "rn", "r", "n", "t", '  ', '    ', '    ' ), '', $code );
		return $code;
	}
?>

まずはCSSファイルを圧縮する関数を用意します。ちなみに、CSSだけでなくJavaScriptにも適用可能です。

Step 2
CSSを読み込んで圧縮する関数を用意
PHP
<?php
generate_bootstrap_css() {
		$output = file_get_contents( get_template_directory_uri().'/library/bootstrap/css/bootstrap.min.css', true );
		return compress_kirki_css_code( $output );
	}
?>

この関数はあらかじめテーマの任意の場所にあらかじめダウンロードしておいたBootstrapファイルを読み込み、コードを圧縮したものをreturnしています。

Step 3
WordPressの関数を利用してインラインに記載
PHP
<?php
wp_register_style( 'bootstrap', false );
wp_enqueue_style( 'bootstrap' );
wp_add_inline_style( 'bootstrap', generate_bootstrap_css() );
?>

まず、wp_register_style( 'bootstrap', false );で「bootstrap」という名前のハンドラーを登録しています。

その次にwp_enqueue_style( 'bootstrap' );でハンドラーをエンキューします。

最後にwp_add_inline_style( 'bootstrap', generate_bootstrap_css() );でStep2までで用意した関数を実行し、Bootstrapの全CSSコードをインラインで読み込みます。

これでBootstrapの全CSSコードをインラインで記述することが出来ました。

CSSを非同期処理に変更する

linkタグのmedia属性は次の3つが存在します。

linkのmedia属性
all

印刷する時もWEBページで表示する時でも利用されるCSS

screen

WEBページで表示する時だけ利用されるCSS

print

印刷する時だけ利用されるCSS

このプロパティを性質を使い、ページを読み込む時は全てのmedia属性の値をprintとし、ページ読み完了後にallに変更することで、CSSの読み込みを非同期にすることが可能です。

WordPressで外部CSSファイルを全て非同期設定に変更する方法WordPressはたくさんのCSSを読み込みますが、それらがレンダリングをブロックするため、Google Page Speed Insightのスコアに悪影響を与えます。そんなときはCSSを非同期処理させてしまいましょう。
Step 1
全てのCSSを非同期処理に変える関数を用意する
PHP
<?php
replace_link_stylesheet_tag( $html, $handle, $href, $media ) {
      return preg_replace( array( "/'/", '/(media)=".+?" */' ), array( '"', 'media="print" onload="this.media='all'"' ), $html );
    }
?>

残念ながら、WordPressにはメディア属性を直接コントロールする便利な方法が用意されていません。そのため、pre_replace関数と正規表現を利用してlinkタグを書き換えます。

Step 2
style_loader_tagにhookする
PHP
<?php 
if ( ! is_admin() ) {
add_filter( 'style_loader_tag', 'replace_link_stylesheet_tag', 10, 4 ); 
} ?>

style_loader_tagフックは「ページにlinkタグが出力される直前に任意の処理を実行するために用意されている」フックです。

引数が4つ用意されています。詳しくは下記を参照ください。

style_loader_tag

レンダリングを妨げるJavaScriptリソースを除外する

JavaScriptの場合は、インラインスクリプトと依存関係がある一部のファイルは遅延させず、それ以外の外部JavaScriptファイルを遅延させるのがオススメです。

しかし、不特定多数の開発者のコードが混在するWordPressサイトの場合、JavaScriptファイルを遅延させる時には、以下を前提としておく必要があります。

  • JavaScriptの読み込み順はいじるべきではない
  • JavaScriptの読み込み位置をいじるべきではない
  • 複数のJavaScriptファイルをひとまとめにしてリクエスト数を減らす施策をとるべきではない。
  • JavaScriptはインライン読み込みにすべきではない

全て自分のコードでサイトが構築されている場合、これらの前提を無視しても問題ないケースがあります。そうだとしても、あなたが高度な知識を持ったWordPress開発者でもない限りは、これらの前提を守るべきです。

それでは、作業を始めましょう。

JavaScriptをインラインで書いてはいけない理由

JavaScriptファイルを遅延読み込みをしていない場合、ソース上で上に書いてあるJavaScriptファイルおよびインラインスクリプトが順番に読み込まれます。

一方で、JavaScriptファイルを遅延読み込みにした場合、インラインスクリプトが先に実行されてしまいます。例えば、jQueryを読み込む前にjQueryの読み込みを前提としたインラインスクリプトが実行されてしまうケースが多く、オススメしません。

JavaScriptを遅延読み込みさせる

JavaScriptに遅延読み込みを設定する方法は2つあります。defer属性を使う方法とasync属性を使う方法です。

WordPressは自分が把握していないスクリプトをページで読み込むことがほとんどです。そのため、defer属性を使うことを強くオススメします。

defer属性とasync属性の違い
defer属性

DOMの読み込みが完了した時、ソース上で「上に書かれているJavaScirptファイルから順番に読み込む」

async属性

DOMの読み込みが完了した時、「ソース上の記載順に関係なくJavaScriptファイルを読み込む」(非同期)

WordPressでレンダリングを妨げるリソースの除外(JavaScript)を行う方法WordPressでレンダリングを妨げるリソースの除外(JavaScript)を行い、ページの読み込み速度とGoogle Page Speed Insightにおける評価向上を図ります。
Step 1-1
全てのJavaScriptを遅延処理を加える関数を用意(全て)
PHP
<?php
function replace_link_script_tag( $tag, $handle, $src ) {
  return preg_replace( array( "/'/", '/ type="text/javascript"/' ), array( '"', ' type="text/javascript" defer' ), $tag );
  break;
}
?>

全てのJavaScriptに非同期処理を加える場合はこちらを選択してください。

Step 1-2
全てのJavaScriptを遅延処理を加える関数を用意(jQueryを除く)
PHP
<?php
function replace_link_script_tag( $tag, $handle, $src ) {
  //Format Change
  switch ( $handle ) {
    case 'jquery-core':
      // code...
      return $tag;
      break;
    default:
      // code...
      return preg_replace( array( "/'/", '/ type="text/javascript"/' ), array( '"', ' type="text/javascript" defer' ), $tag );
      break;
  }
}
?>

jQueryの読み込みを前提としているインラインスクリプトが1つでもある場合、Step 1-1のコードは必ず不具合を起こします。

そのため、基本的にはjQueryだけは遅延処理しないこちらのコードをオススメします。

jQuery以外にも遅延処理をしてはいけないコードがある場合は、引数として渡される$handleの値を調べて除外設定を追加してください。

Step 2
script_loader_tagにhookする
PHP
<?php
if ( ! is_admin() ) {
  add_filter( 'script_loader_tag', 'replace_link_script_tag', 10, 3 );
}
?>

script_loader_tagフックは「ページにscriptタグが出力される直前に任意の処理を実行するために用意されている」フックです。

引数が3つ用意されています。詳しくは下記を参照ください。

script_loader_tag

まとめ

この様に、絶対に必要なCSSはインラインで記述して、その他のCSSは全て遅延読み込みさせることでパフォーマンスの向上が可能です。

プラグインが用意しているCSSの読み込み順を変更することもなく、表示崩れも起きにくいです。

そして、JavaScirptファイルも遅延読み込みを設定することでさらなるパフォーマンス向上が見込めます。

ただし、インラインで読み込まれているJavaScirptが先に読み込まれるようになるため、jQueryなど、インラインスクリプトと依存関係があるJavaScriptファイルは除外することをオススメします。

これで、「レンダリングを妨げるリソースの除外」は完了です。