WordPress
2022.09.01(更新)
ページロード遅延が改善 !レンダリングブロックを防ぐ方法【WordPress / CSS編】
CSSファイルがレンダリングをブロックしているみたいなんだけど、WordPressではどう改善するの?
こんなお悩みに答えていきます。
本記事の内容
- ページロード遅延の概要
- レンダリングブロックの仕組み
- CSSファイルにpreload設定をする具体的な方法
本記事を対象とする方
- フロントエンドエンジニアを目指す方
- Webディレクターを目指す方
- SEO施策担当者
この記事を書いている僕はプログラミング歴2年です。webエンジニアとして”社内転職”に成功しました。
ページロード遅延を改善する理由
RAILモデルって聞いたことはありますでしょうか?
最新のテクノロジーを大衆に分かりやすく解説したり、啓蒙する人たちのことをエヴァンジェリストと言います。なんだかたいそうなネーミングですね。
RAILモデルはそのエヴァンジェリストたち(特にGoogleの)が、Webページの速度の重要性について紹介しているモデルです。
RAILとは、Response,Animation,Idle,Loadの頭文字を取ったものでして、Webサイト・アプリケーションで発生するそれぞれのタイミングの応答時間について目標値を掲げています。
RAILモデルによると、Webページのロードの目標時間は1000ミリ秒 !
つまり1秒です !
ページにアクセスして、ブラウザに表示されるまでたったの1秒 !
この1秒の根拠になっているのが、Jakob Nielsenという方が発表した「Response Times:3 Important Limits」という記事です。
※英語版ですが、Googleの翻訳機能で日本語で表示できるので、是非読んでみてください。
でも皆さんも経験ないでしょうか?Webにアクセスしてレスポンスがなんか遅いなーと思ったことが。
あれって1秒以上経っているからなんです。ある研究では、アクセスしてから3秒以内に完全なレスポンスがないと、ユーザーが待ちきれず離れてしまうなんて発表もあるくらいです。
これ、SEO施策が絡んでくるサイトにとっては死活問題ですね。ページロード遅延を改善する理由はここにあります。
レンダリングブロックとページロード遅延の関係
次にレンダリングブロックとページロード遅延の概要を説明します。
ブラウザは、Webサイトを構成するHTMLファイルのソースを上から順番に読んでいきます。読んだソースのDOMを構築し、ブラウザに表示する作業をレンダリングと言いますが、ブラウザは<head>タグ内のサブリソースファイルを見つける度に、読み込みを一旦ストップして、サブリソースファイルにアクセスするため、レンダリングがブロックされる形になります。
このスキームがページロード遅延の一要因となります。
サブリソースとは、CSSファイル、JavaScriptファイル、画像ファイルのことを差します。
自前で用意したものとは別に、有効化したプラグインのファイルもサブリソースに含まれます。
<head>タグ内のCSSファイルの読み込みによるレンダリングブロックを防ぐには、<link>タグのrel属性を”preload”に変更する必要があります。
preloadはリソースヒントと呼ばれ、ブラウザーの主なレンダリング機構が起動する前に読み込みを始めたい、すぐに必要なリソースを指定することができます。
これにより、そのリソースがより早く利用でき、ページのレンダリングがブロックされにくくなり、性能が向上します。
※MDN web doc 引用
CSSファイルにpreload設定をする具体的な方法
では、preload設定をする具体的な方法を紹介していきましょう。
WordPress編なので、functions.phpに以下のコードを追加します。
- function styleLoaderCss($tag, $handle, $href, $media) {
- // 管理画面ページでは非同期読み込みを適用しない
- if (is_admin()) {
- return $tag;
- }
- // メインのCSSファイルを先に読み込まないと見た目が崩れるためperloadしない
- if (in_array( $handle, ['style'], true ) {
- return $tag;
- }
- // preload属性を追加
- $html = <<<'HTML'
- <link rel="preload" href="%1$s" as="style" onload="this.onload=null;this.rel='stylesheet'" data-handle="%3$s" media="%4$s" />
- <noscript>%2$s</noscript>
- HTML;
- return sprintf( $html, $href, $tag, $handle, $media );
- }
- add_filter('style_loader_tag', 'styleLoaderCss’, 10, 4);
※コードを実行する際は必ずバックアップを取ってください。予期せぬエラーが起こっても責任を負えません。
結論から言うと、読み込むCSSファイルの属性をカスタマイズするためのコードです。それにはフィルターフックのstyle_loader_tagを使います。
ファイルターフックとは、WordPress上の何らかの出力や処理(関数実行)をカスタマイズする機能です。
これにより、デフォルトで設定されている内容を上書きすることができます。
ファイルターフックは様々なものが用意されているので、興味のある方はWordPress Codexをご覧ください。
順番にコードの説明をしていきます。
まずは関数を登録します。名前はなんでも良いですが、今回はstyleLoaderCssとしておきます。この関数は$tag、$handle、$href、$mediaの4つのパラメーターを取ります。
- function styleLoaderCss($tag, $handle, $href, $media)
$tag: | 通常出力される<link>タグ |
$handle: | wp_enqueue_styleで登録したハンドル |
$href: | サブリソースファイルにアクセスするURL |
$media: | media属性 |
WordPressの管理画面ページではレンダリングブロックをする必要がないので、フックをかけず通常のlinkタグを出力させます。
- if (is_admin()) {
- // 管理画面ページでは非同期読み込みを適用しない
- return $tag;
- }
メインのCSSファイルにはperloadはつけません。優先的に読み込まないと、ページ全体の見た目が崩れるためです。
- if (in_array( $handle, ['main-style'], true )) {
- return $tag;
- }
in_array()は配列の値があるかどうかをチェックするPHPの組み込み関数です。最初の引数$handleは探したい値です。2番目の引数には探した値を配列として入れます。この例では、CSSを出力するためのハンドル、つまりwp_enqueue_styleが入り、そのハンドルネームを入れることで、サブリソースファイルを特定しています。配列なので複数のファイルを指定することができます。
- wp_enqueue_style('main-style', get_template_directory_uri().'/style.css',array(),date("YmdHi"));
※’main-style’がハンドルネームです
3番目の引数は入った値の型比較を行います。デフォルトはfalseで比較を行わない設定になっていますが、trueを入れて型比較をしないと予期せぬエラーが起こり得るので、trueにしておきましょう。
ここからがCSSファイルの属性をカスタマイズする内容、つまりpreload属性を付与するコードです。
- $html = <<<'HTML'
- <link rel="preload" href="%1$s" as="style" onload="this.onload=null;this.rel='stylesheet'" data-handle="%3$s" media="%4$s" />
- <noscript>%2$s</noscript>
- HTML;
- return sprintf( $html, $href, $tag, $handle, $media );
$htmlという変数に、ヒアドキュメントを使って文字列を代入します。ヒアドキュメントとは、改行や引用符などを含む任意の文字や数字を、指定した通りに文字列リテラルとすることができるものです。簡単に言うと、長めの文字列を扱う際に便利な書き方で、シングルやダブルクォーテーションで囲って文字列とする意味合いと同じものです。
リターンしているsprintf()は、PHPの組み込み関数で、フォーマット化された文字列を返すことができます。
sprintf()に入れる1番目のパラメーターはフォーマット形式を入れます。この例では、ヒアドキュメントを使って文字列を代入した$htmlとなります。
2番目以降は、このフォーマットに入れたい値を指定します。
sprintf()の詳細はPHPマニュアルで確認できるので興味のある方は確認してみてください。
最後にフィルターフックの関数を実行して終了です。
- add_filter('style_loader_tag', 'styleLoaderCss', 10, 4);
では、chromeのDevtoolを開いてソースを確認してみましょう。
preload設定前と設定後のソースコードに、”rel=styleSheet”が入っています。なぜ”rel=preload”じゃないのかと疑問に思う方もいると思いますが、あくまでpreloadは先読みを行う設定であって、スタイルシートを適用するものではないからです。
CSSファイルを適用するには”rel=stylesheet”になってないといけません。preloadが機能しているかどうかはPageSpeed Insightで、”レンダリングを妨げるリソースの除外”の項目を確認するのが良いでしょう。
別の記事にて、JavaScriptファイルのレンダリングブロックを防ぐ方法も解説していますので合わせてご覧ください。
今回のまとめ
今回はCSSファイルのレンダリングブロックを防ぐ方法について紹介しました。最後まで読んで頂きありがとうございました。
functions.phpにフィルターフック’style_loader_tag’を設定する
PHP組み込み関数のsprintf()を使い、設定したい文字列をフォーマット形式にする
preload設定後は、PageSpeed Insightsで結果を確認する