長かったLCPとの戦いが一段落ついたので備忘録的に。
はじめに
LCP (Largest Contentful Paint) は、PageSpeed Insights (Lighthouse) で計測されるパフォーマンスに関する指標の1つです。Googleが重要としている健全なウェブサイトであることを測る3つの指標 「Core Web Vitals」 のうちの1つでもあります。
LCPはビューポート内に表示される最も大きいコンテンツのレンダリングにかかった時間(秒)が値としてレポートされ、これが2.5秒以内であれば良好であると判断されます。さらにPageSpeed Insights のモバイルの診断はローエンドモバイルかつ低速回線でスロットリングされるため、思った以上に遅くレポートされることが多いと思われます。
今回はWordPressで構築されたサイトで行ったLCP改善の施策を整理していきます。
やったこと
Googleのドキュメントを読んだり、Lighthouseの結果からおすすめされた施策を試してみて効果の高かったものを列挙していきます。
キャッシュを有効化する
標準のWordPressは投稿を表示する際に毎回サーバーサイドでPHPを実行するようになっています。投稿データはDBに永続化されており、その投稿データをテンプレートに渡して描画することになります。
このPHPの処理とDBへのアクセスがパフォーマンスのボトルネックになりやすいため、キャッシュをすることでこれを減らそうという試みです。
キャッシュ系プラグインを使う
キャッシュ系プラグインはプラグイン毎にキャッシュの仕組みが異なります。「永続オブジェクトキャッシュを使用してください」が気になったのでコアを覗いてみた で触れたオブジェクトキャッシュはメモリ上のキャッシュでサーバーサイドのPHPの処理を高速化しますが、今回は後述するCDNとの相性を考慮して WP Fastest Cache を使用しました。
WP Fastest Cache はキャッシュの設定を有効化することで投稿データをhtmlファイルに出力します。htmlファイルが一度生成されると以降はそのhtmlファイルを直接読み込むことになります。
これにより、PHPの実行とDBへのアクセスの回数が削減され、パフォーマンスの改善が見込まれます。
CDNを使う
CDNはコンテンツをクライアントに近いエッジロケーションから配信する仕組みで、コンテンツを保持するサーバーへのリクエストは行わず、コンテンツをキャッシュしたサーバーがコンテンツを返します。元々のコンテンツを保持するサーバーをオリジンと呼びます。
利用するCDNと設定によってキャッシュの動作は変わってきますが、WordPressではパスパターンでのキャッシュを採用することが多いかと思われます。
キャッシュ系プラグインの WP Fastest Cache は、wp-content/cache
配下に投稿データのhtmlを出力しますし、画像ファイルは wp-content/uploads
、大抵のテーマやプラグインが生成する独自の静的ファイル群も概ね wp-content
配下ですので、wp-content
配下をキャッシュできる設定が効果的かと思います。
ちなみにAWS Lightsail ではWordPress最適設定として、wp-includes/*
と wp-content/*
をキャッシュ対象としています。
JavaScriptの読み込み時間を削減する
JavaScriptファイルのサイズを減らしたり、読み込みを遅延させることはパフォーマンス改善に繋がります。JavaScriptの読み込みはダウンロードだけではなくブラウザによる解析やコンパイルといったオーバーヘッドが関わってくるため、同程度のサイズの画像より処理コストが高く時間がかかるのだそうです。
読み込みを遅延させるプラグインを使う
Google Analytics や Google Tag Manager と連携している場合は、該当のイベントを発火するjsの読み込みが発生します。このjsの読み込みに時間がかかってしまうようです。Lighthouseでは改善方法としてjs自体の削減か読み込みを遅延させることを提案されます。
該当のjsの enqueue を遅延させれば良いのですが、Google系サービスとの連携はプラグインを利用しているケースが多いと思いますので愚直にやろうとすると骨が折れそうです。
Flying Scripts では、遅延読み込みさせたいjsのキーワードを設定することで該当のjsを(おそらく部分一致で)特定し、指定した秒数だけ読み込みを遅らせることができます。
Tag Manager だったら↓このように設定すればOK。
仕組みとしては、指定された秒数が経過したあとにDOMに突っ込んでいるようで、結構な力技でした。
const loadScriptsTimer = setTimeout(loadScripts,<?php echo $timeout ?>* 1000
注意点としては、上記の通り力技なので Tag Manager の設定によってはタグのイベントが発火されない可能性があるかもしれません。十分にテストを行った方が良さそうです。
使っていないJavaScriptを読み込まない
テーマやプラグインによっては標準で enqueue されているjsがあるかと思いますが、そのjsを使っている機能が一部だけで該当機能を使わない場合はjsを読み込まないようにするということも出来ます。
例えば、カルーセル機能を有したウィジェットのために読み込まれている Slick.js は、当該ウィジェットを利用しなければ不要なはずです。
こちらは functions.php
に数行追加するだけでOKです。
function deregister_unnecessary_scripts() {
wp_deregister_script('handle');
}
// 注意: hookのタイミングはenqueueされた後である必要がある
add_action('wp_enqueue_scripts', 'deregister_unnecessary_scripts');
投稿の構成を変える
冒頭にも書きましたが、LCPはファーストビューで読み込まれるコンテンツのうち、最もサイズの大きい要素の読み込みにかかった時間です。よって、サイズの大きいものはファーストビューに含めないという方法もありかと思います。単純にサムネイルをタイトルの直下に配置しないとかが考えられます。
おわりに
LCP改善をやってみて、WordPressで対策するのは様々な工夫が必要だなと感じました。結局はテーマやプラグインに依存するところが多いですので、今回記載した施策がすべてに当てはまるものでは無いかと思います。また、「画像を WebP に変換する」「静的ファイルをminifyする」など、記載しなかった施策もいくつかあります。このあたりは別の機会にまとめられれば。。