WordPress: style.cssをインライン化する

サイトの表示速度を向上させる方法の一つに、style.cssなどのcssファイルをインライン化するというものがあります。
WordPressのテーマはファイルから読み込むものが多いので、それをインライン化する方法を考えてみます。

やりたいこと

スタイルシートをlinkタグで読み込んでいるとします。

  • <link rel='stylesheet' id='my_theme_style-css' href='http://xxxx.com/wp-content/themes/my-theme/style.css?ver=5.9.3' type='text/css' media='all' />
AFFS Simple Code Viewer
Copy

これを、html中にstyleタグでインライン化します。

  • <style>
  • .aaa{
  • color:red;
  • }
  • </style>
AFFS Simple Code Viewer
Copy

タイトルではstyle.cssとしていますが、他のファイルでも有効な方法を考えてみます。

前提条件

wp_enqueue_style()関数を使用して、スタイルシートを登録していることが前提条件です。

wp_enqueue_style()関数を使用しないで出力している場合は、出力している箇所を探して書き換える必要があります。
苦労して書き換えても、テーマ更新などで元に戻ってしまう可能性があります。
この場合は、あきらめたほうがよさそうです。

wp_enqueue_style()関数が使用されているかどうかを確認する方法を次の記事で紹介しているので、読んでみてください。

WordPress: enqueueされているscriptとstyleの一覧を表示してみる

インライン化の手順

では、インライン化してみましょう。
手順は、とても単純です。

インライン化手順
  1. wp_dequeue_style()関数で、目的のスタイルをキューから削除する
  2. ファイルの内容を読み込む
  3. 読み込んだデータをstyleタグで囲んでecho出力する

WordPressはキューを元にlinkタグを生成する直前に、wp_print_stylesアクションを呼び出しています。
タイミング的に、このアクションで上記の手順を実行するのがよさそうです。

コード例

  • add_action( 'wp_print_styles' , 'my_print_styles' );
  • function my_print_styles(){
  • wp_dequeue_style( ハンドル );
  • $css_file = get_template_directory() . '/style.css';
  • $css_data = file_get_contents( $css_file );
  • echo '<style>'.$css_data.'</style>';
  • }
AFFS Simple Code Viewer
Copy

読み込みに失敗したときの処理をおこなっていないので、実際のコードはもう少し複雑になると思います。

ハンドルは、linkタグのid属性から -css を取り除いたものです。
id='my_theme_style-css' なら、 'my_theme_style' です。

公式ディレクトリ対応

file_get_contents()関数は非推奨となっていて、公式ディレクトリに登録するなら使わない方がいいようです。
WordPressの本体で使っているので、使い方によるんだろうなとは思いますが、気になる方は WP_Filesystem() を使用してください。

  • require_once( ABSPATH . 'wp-admin/includes/file.php' );
  • add_action( 'wp_print_styles' , 'my_print_styles' );
  • function my_print_styles(){
  • if ( WP_Filesystem() ) {
  • global $wp_filesystem;
  • wp_dequeue_style( ハンドル );
  • $css_file = get_template_directory() . '/style.css';
  • $css_data = $wp_filesystem->get_contents( $css_file );
  • echo '<style>'.$css_data.'</style>';
  • }
  • }
AFFS Simple Code Viewer
Copy

WP_Filesystem()関数は初期状態では定義されていません。
そのため、require_once()でソースコード(file.php)を読み込んでいます。

file.phpは2500行と、それなりに大きいです。
その分処理の負荷が増えます。
公式ディレクトリに登録するとしても最初はfile_get_contents()関数を使用して、ダメって言われたら変更したほうがいい気がします。

スタイルデータの最適化

ファイルから読み込まれたスタイルデータには、コメントや改行など必要がないものが含まれています。
特にstyle.cssにはテーマの情報などが含まれていて、そのまま出力するのは少し躊躇してしまいます。

そこでコメントや改行、ムダな空白を削除してみます。

考え方としては、正規表現を使って文字の置き換えを行います。

  • function css_minify( $css ){
  • $css = preg_replace( '#/\*.*?\*/#s', '', $css);
  • $css = str_replace(array("\r\n", "\r", "\n", "\t"), '', $css);
  • $css = preg_replace( '/\s{2,}/', ' ', $css);
  • return str_replace(array('{ ','} ',': ', '; ',', '), array('{','}',':',';',','), $css);
  • }
AFFS Simple Code Viewer
Copy

ダブルやシングルのクォーテーションで囲まれたケースを考慮していませんが、特殊な例と割り切ってコードを作成しています。
またURLの指定方法によっては、置き換えが必要になるかもしれません。
元となるファイルを確認する必要があります。

ファイルからデータを読み込んでecho出力する前に、この関数を呼び出します。

  • echo '<style>'.css_minify($css_data ).'</style>';
AFFS Simple Code Viewer
Copy

これで余分なものが削除されると思う・・・

お手軽な方法(サイズ制限あり)

前項で紹介した方法が最適解だと思いますが、実はWordPressの機能としてスタイルファイルをインライン化してくれる機能があります。
関数を一回だけ呼び出すだけなので、とてもお手軽です。

ただし、合計サイズが20000バイトまでという制限があります。
また、読み込んだデータから余分な文字を削除できません。
そのまま出力されます。

キューに'path'データを追加

wp_maybe_inline_styles()関数は、スタイルシートファイルを読み込んでインライン化してくれる関数です。
この関数は、linkタグが出力される前に呼び出されます。

インライン化対象となるファイルは、次の条件で決定されます。

インライン化の条件
  1. キューハンドルに'path'データがある
  2. ファイルサイズが小さいものから合計20000バイトまで

①'path'データは、wp_style_add_data()関数で追加します。

wp_style_add_data()の構文

wp_style_add_data( ハンドル , 'path' , ファイルのパス )

②制限サイズはstyles_inline_size_limitフィルターで変更できます。

使用例

テーマを自作している場合

テーマを自作している場合は、wp_enqueue_style()関数を呼び出した後にwp_style_add_data()関数を実行します。

  • add_action( 'wp_enqueue_scripts', 'my_theme_enqueue_scripts' );
  • function my_theme_enqueue_scripts(){
  • $handle = 'my_theme_style';
  • $style_file = '/style.css';
  • wp_enqueue_style( $handle, get_template_directory_uri() . $style_file );
  • wp_style_add_data($handle,'path',get_template_directory() . $style_file);
  • }
AFFS Simple Code Viewer
Copy

テーマが自作でない場合

自作ではないときは、wp_enqueue_style()関数の後にwp_style_add_data()が実行されるようにスケジューリングする必要があります。

wp_maybe_inline_styles()関数はスタイルのインライン化処理の前に、styles_inline_size_limitフィルターを呼び出しているので、相乗りさせてもらいます。

  • add_filter('styles_inline_size_limit','my_styles_inline_size_limit');
  • function my_styles_inline_size_limit($total_inline_limit){
  • wp_style_add_data('my_theme_style','path',get_template_directory() . '/style.css');
  • return $total_inline_limit;
  • }
AFFS Simple Code Viewer
Copy

インライン化すれば速くなるというわけではない

インライン化すると速くなるのは、ブラウザからWebサーバーへのリクエストが減るからです。

ブラウザのアドレスバーにURLを入力すると、Webサーバーにページのデータを送るようにリクエストされます。
そして送られてきたデータにlinkタグがあると、cssファイルを送るようにリクエストされます。
インライン化されているとリクエストされないので、その分速くなるわけです。

しかし、ブラウザにはキャッシュという仕組みがあります。
この仕組みにより、一度読み込んだデータを一定期間保存しておくことで、次回のリクエストを省略することができます。
つまり2回目以降は、速いのです。

ですがインライン化されていると、毎回同じデータが送られてくることになります。
ムダな気がしますね。

推奨されるのはファーストビューに関する部分をインラインで、その他をlinkタグで読み込みます。
自分でテーマを作成したならともかく、既存テーマでそんなことはムリですね・・・