PageSpeedモバイルスコア100を実現したFCP/LCP/TBT/CLSにしラボ式施策22
PageSpeed Insightsスコアでモバイル100を達成したFCP/LCP/TBT/CLS施策22個です。パフォーマンスのボトルネックを全部潰します。
※ウェブサイトの規模、設計、ビジネスフェーズ、プロジェクト体制などによりCore Web Vitalsはベストな対策が異なります。
施策の効力スコープ
WordPressの場合、以下3タイプの施策効力スコープが有ります。ビジネスロジックを考慮して、ランディングページ、商品ページ、集客向けのブログページ、フォームが有るCTAページ、個々のページ、トップページなど、必ず、パフォーマンス対策を施すページを決める必要があります。
- WEBサイト全体に対して効かせる施策
- 機能単位でグルーピングしたページのグループ別に効かせる施策
- フォームやボット判定など特定機能のjavascriptの有無や画像/動画の有無などでグループを作り分類します
- 個々のページで効かせる施策
にしラボは、運用効率やマーケティング戦略などを考慮し、PageSpeed Ingightsモバイルスコア100実装対象として「トップページ」を「3. 個々のWEBページで効かせる施策」としてパフォーマンス対策の最重要ページとしています。次に「サービス配下の個々の商品ページ」を重要視しています。他ページは、重要視ページで実施された施策の多数がWEBサイト全体に効果を波及するため、「1. WEBサイト全体に対して効かせる施策」として扱い、運用ルールを守ることで、十分なパフォーマンスをWEBサイト全体で安定的に確保できる状態となっています。
前提
- 3rdパーティタグのNitroPackによる重複読み込み対策(除外設定)が完了していること。
- robots.txtは、NitroPackとCloudflareの双方で除外、オリジンサーバにファイルがBOM無しUTF-8で配置されていること。
- HSTS有効
- Cloudflareで有効にすることでQuallys SSL Labs がA+になるケースは比較的に多いです。
- Quallys SSL Labsは最新SSLセキュリティまでは追従出来ていないですが、最低限のSSLセキュリティチェックとしては有用です。
にしラボ式の特徴
サーバー種別を一切問わず、運用と並行して導入しやすく、基本的なセキュリティ対策と共存しやすい点にあります。
アプリケーション側チューニングによるオリジン軽量化、軽量化されたコンテンツをNitoPackで最適化、Cloudflare Cache Rules/WAF セキュリティ カスタムルールの活用、として全体最適化を行います。
- WordPress側はテーマ、プラグイン、本体(コア)の更新を継続出来る。
- サーバー種別問わず導入可能(レンタル共有サーバー、VPS、クラウド)。Preload Cache Warmupの精度を確保出来なくてもオリジンサーバの負担を大きく減らせます。
- NitroPackはコンテンツの最適化(HTML含む)とHTMLを除く最適化済アセットをキャッシュ
- Cloudflareでデバイス別キャッシュキーを設定し、NitroPackにより最適化されたHTMLをエッジPoP運用。
- 開発が難しいPreload Cache Warmupまで行わず、最短3ヶ月で導入から運用までのサポート完了(WordPress Theme Ligtningの場合)。
- Preload Cache Warmupのベターソリューション:Preload Cache 作業の陥りがちで可視化しにくい問題点をCloudflare Cache Rules と 階層型キャッシュで補完します。
- Quallys SSL Labs は A+ でSSLのセキュリティを最低限確保。
- Solid Security Basicなど、セキュリティプラグインとの共存が前提。
- アップデート永続が前提
- 運用トラブルでXMLサイトマップが404になり、キャッシュパージやPreload Cache Warmupが出来ない場合でも、オリジンサーバ側でアプリケーション側のチューニングが済んでいるため、危機的なパフォーマンス状況になりにくい。
- ページビューが増えてきた際は、スケールアップ対応可能。
コンテンツが複雑になるほど、その後の工程を最適化する「にしラボ式」の戦略が全ボトルネック対応となり、最終的な成果を決定することになります。
3rdパーティタグ戦略
PartytownによってWeb Workerで扱うため、メインスレッドでは3rd Partyタグを扱わず、メインスレッド内で3rd Partyタグのロングタスクによるブロックが発生しません。
- GA4:有
- Wicle(Karte):有(セッションリプレイ無効)
- セッションリプレイを有効とした場合、PageSpeedモバイルスコア95以上安定程度の実績です。
- Cloudflare Web Analytics(Real User Monitoring):有 ※DNSによる導入。
- クッキー同意管理(Cookiebotなど):無
CDN / Core Web Vitals対応Saas 利用状況
- Cloudflare無料プラン
- NitroPack Starter
- エックスサーバー スタンダードプラン
上記の通り、にしラボ式はサーバ種別を問わず導入可能なため、Webサイト開設初期から安定したパフォーマンスを発揮できます。
FCP/LCP/TBT/INP/CLSにしラボ式施策22
にしラボ式は、パフォーマンス対策のあるあるに沿っており、技術負債の総洗い出し、WEBアプリケーション内部の機能単位オーバーホール、総洗い出しに対する潰し込みと仕組み化などを含む施策22個です。Step.1からStep.3までの3ステップに別けられます。無限のもぐらたたき作業でもあるため、効率を考えながら取捨選択することが推奨されます。
Step.1【削り】 → Step.2【最小機能内製化】 → Step.3【最適化】
- 「削り」は、パフォーマンス対策の根幹で最重要工程です。施策対象ページの機能をリストアップし、削り可能な部分を洗い出して削り作業を行います。
- 「最小機能内製化」は、極限までDBクエリコストなどを下げるため、セキュリティ的にシビアな機微情報を除き、恒久的かつ公開され運用上で支障が無い情報項目(会社名や代表電話番号など)をソースコード内でグローバル変数化してハードコーディングします。徹底的に機能(クエリ)最小化を行います。git必須です。ここまでやるかどうか?は技術チームの経営判断によります。
- 「最適化」は、Saas課金の大小判断も必要になりますが、全てのStepを丁寧に行うことでSaas投資最小で最大の効果を精度高く安定的に出すことが可能となり、長期で非常に良い施策となります。
Step.1【削り】「ファイル容量の最小化」と「遅いクエリや機能の無効化」
- PageSpeed Insightsの事前計測をします。
- ブラウザの開発者ツールのNetworkでpainting(描画)の遅い処理やファイルを探す(404などのステータス問題も探す)
- 開発者ツールのコンソールでpainting(描画)を遅くしているjavascriptエラーを深堀り、ソースコードから機能や原発部を特定する
- Webアプリケーションの内部クエリを可視化して、遅いクエリを探す
- 冗長で処理が遅い機能を探し、無効化する
- 機能別のjavascriptの読み込み範囲を必要な箇所だけに最小化する
- PageSpeed Insightsの事後計測をします(適宜、必要に応じて作業中も計測してください)。
※「遅いクエリや機能の無効化」に対する最小限の機能内製化は、事後計測の精度を上げるため、次のStepで実施します。
✔:優先度高(効きやすい)
○:優先度中
| 施策No. | 施策 | FCP | LCP | TBT(INP) | CLS | 補足 |
|---|---|---|---|---|---|---|
| 01 | 不要プラグイン/テーマの削除 | ✔ | ✔ | ✔ | ○ | プラグイン選定は基本 |
| 02 | プラグイン単体における不要機能無効化 | ✔ | ✔ | ✔ | ○ | 機能単位で無効化できる「VK All in One Expansion Unit」がおすすめ |
| 03 | 遅い機能の削除(php/javascript) | ✔ | ✔ | ✔ | ○ | ブラウザ開発者ツールのNetworkとConsoleで探す。※javascriptは、リファクタリングコストが高いので、他の施策を行ってもスコアが改善しないときに行う方針にするのも大事ですが、ページ種類毎の特徴に合わせた条件分岐による問題を起こしにくい削除が肝です。 |
| 04 | Query Monitorプラグインで遅いクエリ特定/除去 | ✔ | ✔ | ✔ | 各フックの優先度も可能な範囲で見直し。保守コスト対策としてクロージャ(無名関数)利用はなるべく避ける。 | |
| 05 | AAA Option Optimizerで不要autoload optionsを無効化/削除※ | ✔ | ✔ | ✔ | wp_optionsへの不要なDBクエリを無くす。 | |
| 06 | アンインストール済プラグイン/テーマのDB残骸削除※ | ○ | ○ | アンインストールにより不要となったDBテーブルを削除。 | ||
| 07 | 大容量の文字フォント読み込み削除 | ✔ | ✔ | ✔ | 文字フォントは細かく対策を行うと手間が大きいため、重たいフォントはすべて無効化しています。 | |
| 08 | データベース内ログ(保存機能)削除 | ○ | ○ | WordPressデータベースをログ肥大化させないようにS3やR2、CloudWatchLogsなど、その他を使う。 | ||
| 09 | 大容量アイコンフォント読み込み削除&軽量アイコンフォントに入れ替え | ✔ | ○ | ○ | FontAwesomeなどの容量が大きいアイコンフォントをheroiconsやTabler Icons の軽量SVGに変える | |
| 10 | reCaptcha→Cloudflare Turnstile | ✔ | ✔ | ✔ | Google reCapture有料化のため | |
| 11 | favicon.icoをwp_headで読み込み | ○ | ○ | faviconのステータス404を開発者ツールのNetworkから無くす。容量小さいサイズパターンでなるべく軽く。 | ||
| 12 | 不要CSS読み込み削除(ページ種類単位) | ✔ | ✔ | ○ | ○ | 読み込むcssファイルをページ種類で別けて読み込みを最小限に制限。CF7などで重要。 |
| 13 | 不要javascript読み込み削除(ページ種類単位) | ✔ | ✔ | ✔ | 読み込むjavascriptファイルをページ種類で別けて読み込みを最小限に制限。 | |
| 14 | データベース内不要データ削除※ | ○ | ○ | 必要に応じて行ってください。リビジョンはwp-config.phpにて最低限でdefineします。 |
データベース内不要データ削除対象と対処方法(施策No.5,6,14)
wp_optionsの autoload(フロントのTTFB悪化原因)- AAA Option Optimizerプラグインを利用
- 期限切れトランジェント
- WP-Optimizeなどのプラグインで削除
- SQLで削除
- 投稿リビジョン/自動保存
- プラグインを避けてwp-config.phpでdefineする
- WP-Optimizeなどのプラグインで削除
- SQLで削除
- スパム・ゴミ箱コメント
- WP-Optimizeなどのプラグインで削除
- SQLで削除
- 孤立metadata各種(post , user , comment)
- WP-Optimizeなどのプラグインで削除
- SQLで削除
- 使っていないプラグインの残骸(
wp_optionsのオプションや独自テーブル)- 独自テーブル名からプラグイン名を特定する。
- ログ系テーブル(Security/WAF/フォーム/統計などの履歴)
- データベース保存を辞めて、他の保存運用方法に変更する
- 不要なCronイベントの点検・削除
- WP Crontrolなどのプラグインで削除
- SQLで削除
Step.2【最小機能化】最小機能で実装内製化
「必要な機能」と「ブラウザ描画時に負荷最小限」をWordPressコア/テーマ/プラグインの更新永続と運用負荷最小となるように実装します。
| 施策No. | 施策 | FCP | LCP | TBT(INP) | CLS | 補足 |
|---|---|---|---|---|---|---|
| 15 | 最小機能で実装(遅いプラグインや機能の削除の補完) | ✔ | ✔ | ✔ | ○ | JSON-LDなどデータベースへのSQLクエリが多く処理が長引きやすい機能は最小機能内製化の効果が出やすい。 にしラボでは、パンくずリストを除く主要機能はほぼ全部自前で実装しているため、WPテーマ問わず対応可能です。 |
| 16 | javascriptをfooter読み込みへ(可能なものだけ) | ✔ | ✔ | ○ | プロジェクト要件との相談必要 | |
| 17 | LCP用ショートコードプラグイン実装 | ✔ | LCP運用を簡単にする。LCP用html自動化。.webp対応。 | |||
| 18 | WebWorker/ServiceWorkerでGA4などの計測/追跡の3rd Partyタグをメインスレッドから除去 | ○ | ✔ | Partytownを利用。固定IP除外などはCookieも同時に活用して実装。 | ||
| 19 | ランディングページ用phpテンプレート実装 | ✔ | ✔ | ✔ | ○ | 不要機能を読み込まない。ハイパフォーマンスなLPをWordPressで運用出来ます |
Step.3【最適化】Cloudflare、NitroPack、画像ファイルの最適化チューニング
CDNキャッシュ、WAF、Minify(圧縮)、preload、Lazyなどの最適化です。
※.htaccessのキャッシュ保持期間設定を忘れないようにしてください。
| 施策No. | 施策 | FCP | LCP | TBT(INP) | CLS | 補足 |
|---|---|---|---|---|---|---|
| 20 | Cloudflare無料プラン(※1)チューニング | ✔ | ✔ | ○ | preload向け設定、WAF穴開け、各種APO | |
| 21 | NitroPack(Starterプラン)チューニング | ○ | ✔ | ✔ | ✔ | preload向け設定、lazy除外設定、CriticalCSSなど各種最適化設定、Minify関連設定 |
| 22 | EWWW Image Optimizerで画像最適化+WebP(AVIF)生成 | ○ | ✔ | ○ | 画像ファイルの最適化 |
※1 Cloudflare無料プランは、WAFやCDNが無料というプランでドメイン年間料金(原価提供なので比較的に安い)は別途必要です。
Delayed Scripts、LCP Image Preload、Cache Excluded
ページビューが多いWebサイトは、NitroPack Starter(pageviews:8,000/mo 、traffic:5GB/mo CDN)ではなく、NitroPackのPlus($22.00/month)以上が選択肢となっており、ページビューが少ないなりにコスパ最高(NitroPack Starterプラン)を狙って、LCP Image Preloadは、.webpだけ前提で<picture><source>のフォールバック無しで<figure><img>(srcsetによるフォールバックのみ)phpにて最小機能実装しました。
- Delay non-critical resources(javascript)
- 非クリティカルリソース(javascript)遅延
- 初回ユーザー操作までJS実行を遅延する:スクロール引っ掛かり(Scroll jank)になる場合があり、無効化しています。
- LCP Image Preload
- ブラウザに「この画像(=ファーストビューなどの大きなヒーロー画像/LCP候補)をいちばん先に取りに行って!」と早出し指示を出す。
- 独自に実装(初期はCloudflare Workers、PageSpeed Insightsで90以上で安定してきたらアプリケーション側の機能として実装やりなおし)。既製品プラグインでは最適化不足なパターン有。
- Cache Excluded
- GA4や追跡調査系のリマーケタグ(Partytown WebWokerとなるため最適化から外す)、フォーム関連のjavascript、独自実装のLCP画像、その他の戦略的な読み込みコントロールリソースをキャッシュ除外。
- 除外設定はNitroPackなどのCore Web Vitals最適化Saasを利用するうえで、極めて重要です。
基本的なhtml/cssなどの改善
簡単な作業であるため施策には記載していませんが、細かくPSIのアベレージスコアを押し上げてくれるため、めんどくさいですが対応かつ運用ルール化を強く推奨します。
- 見出し順序の最適化
- 背景色と前景色のコントラスト比確保
- 画像alt属性付与
- フォームのラベル属性付与
- モバイルにおけるタップターゲットのサイズや間隔(カテゴリやタグなどのタクソノミーまわりにおける、ユーザービリティを求められます)
- robots.txtをBOM無しutf-8でオリジンサーバに配置
- ネストが深く複雑なDOMによる再レイアウトCLS発生
キャッシュ保持箇所のシンプル化
開発や運用をキャッシュで複雑化してしまう事態を避けるため、レンタル共有サーバーのエックスサーバーのキャッシュ機能、WordPressのキャッシュ機能は一切使っていません。キャッシュ管理はCloudflareとNitroPackの2箇所に集中させています。唯一、サーバで.htaccessにキャッシュ保持期限を持たせています。
NitroPackとCloudflareでキャッシュパージを行えば事足りる設計としたことで、トラブルや検証時、キャッシュ影響によってうまく作業できない事に後から気付いて時間を蝕むことが無くなりました。
.htraccessの記載は可読性が低いため、問題の原発部をしれっとスルーしてしまうリスクが高いため、わかりやすいコメントが重要になっていきます。
ブラウザキャッシュ依存の排除
よくあるケースは、ブラウザキャッシュに依存しすぎて、HTMLやCSS、JSの更新が反映されない問題が頻発し、「ブラウザのスーパーリロードで解決」という運用が常態化しているケースです。ブラウザのスーパーリロードはユーザー負担であり、問題解決になっていません。
キャッシュするコンテンツ、キャッシュしないコンテンツを決めて、さらにキャッシュをCDNに持たせてサービス提供側によるキャッシュコントロールを可能とすることで、ユーザー側の体験はかなり改善され、オリジンサーバへの負荷も緩和されCVR向上につながります。
不要なjavascriptの制御
機能単位のページグループ別にjavascriptの読み込みを最小限にしぼることが非常に大切です。ブラウザの読み込み負荷を最小に抑えます。WebWorkerの活用による3rd partyタグのメインスレッドブロック回避なども有効です。
Preload cache warmup
スコア100安定化に向けて重要かつ複雑なキャッシュミス対応です。NitroPackのCache warmupだけに依存しないようにするため、世界中に数多く存在するCloudflareのエッジ(PoP)に対するpreload cache warmupの精度確保として、以下の条件を加味する必要があります。台北を考慮するとGCP Cloud Functionsが良さそうです。中国本土は、対象から外します。
- 複数リージョン
- 日本国内(大阪KIX、東京NRT、福岡、那覇)
- アジア、オセアニア、北米、etc...
- UserAgent
- モバイル、デスクトップ
- クッキー
- ABテスト
- ユーザーサインイン
- その他
- レスポンスヘッダ cache 状況確認
- NitroPack:
x-nitro-cache - Cloudflare:
cf-cache-status
- NitroPack:
Preload cache warmupは、訪問者が多いウェブサイトであれば訪問者によるwarmupを許容する事も合理的な戦略となります。ただ、キャッシュパージ直後のCDNにおける非キャッシュ DYNAMICステータス時の機械損失が大きいビジネスでは注意が必要です。
訪問者が少ないにしラボWebサイトでは、機会損失を最小限にするためwarmupの精度確保を重要課題としています。
NitroPackのpreload cache warmup
NitroPackは、Preload warmupの対象URLの一覧として、XMLサイトマップ生成の仕組みが比較的にモダンなYoast SEO や All in one SEOプラグインなどのxmlサイトマップを推奨しています。WPデフォルトのサイトマップは表示される情報が少ないです。XML Sitemap Generator for GoogleプラグインもWPデフォルトのサイトマップも、リクエストを受けるたびにDBクエリが発生するロジックとなっています。対するYoastやAIO SEOは記事作成、更新、削除をトリガーにキャッシュされたxmlサイトマップが更新されるロジックということで、パフォーマンス観点のTBT、INP対策としても推奨されます。
YoastやAIOSEOは、不要な機能も含めて強制的に多くの機能が有効(細かい機能単位で無効化できない)となるため、パフォーマンスチューニングの際には悩ましい側面があります。
日本の場合、NitroPackはUnited KingdomのNitroPackサーバからPreload warmupが行われます。しかし、日本に対するwarmup効果はほぼ無いため、Cloudflare APOとの併用が推奨されます。
Preload cache warmupの失敗と【削り】セーフティネット
ちょっとした作業によってxmlサイトマップの404が発生すると、NitroPackでXMLサイトマップを使うpreload cache warmupは利用出来なくなります。xmlサイトマップをステータス200として復旧するまでの間、ページ数が多いWEBサイトでは、Step.1【削り】のパフォーマンス土台がダイレクトに露出します。運用/開発を継続していると、xmlサイトマップの404が発生しないとは断言できないため、セーフティネットとして【削り】は非常に重要です。
Core Web Vitals最適化施策の選択
Googleのウェブに関する主な指標(Core Web Vitals)の基準を満たすため、運用を考慮しながら恒常的に安定させることが出来、スコア改善幅が大きい施策を中心に選択することになります。
PageSpeed Insights(Lighthouse)計測結果でTimeロスが大きい順番並べてみて、上から対応することが推奨されます。
ウェブに関する主な指標(Core Web Vitals)https://web.dev/articles/vitals?hl=ja#core-web-vitals
- Largest Contentful Paint(LCP): 読み込みパフォーマンスを測定します。優れたユーザー エクスペリエンスを提供するには、ページの読み込み開始から 2.5 秒以内に LCP を実現する必要があります。
- Interaction to Next Paint(INP): インタラクティブ性を測定します。優れたユーザー エクスペリエンスを提供するには、ページの INP を 200 ミリ秒未満にする必要があります。
- Cumulative Layout Shift(CLS): 視覚的安定性を測定します。優れたユーザー エクスペリエンスを提供するには、ページの CLS を 0.1 未満に保つ必要があります。
作業期間
にしラボでは、本番環境のみ単環境でGithub WorkflowによるサーバへのシンプルなSCPで作業をしました。
モバイルを含むスコア90以上には2周間程度で到達しています。スコア100は3週間目で到達し、その段階で95から100程度のスコアのブレが顕著になり、スコア100継続安定化を目指してさらに6週間チャレンジし、トップページ https://4649-24.com で少しずつ安定100の確率が上がってきました。
テスト環境や本番環境など多環境が存在し、規約を遵守しながら作業を行うエンタープライズのプロジェクトでは、理想としては個々の施策1個ずつアジャイルに実装することが望ましいです。
エンタープライズ案件でスケジュールを明確に作成する必要がある場合、テスト環境であってもCI/CDなどデプロイから検証完了までの1サイクルが長いため、テスト環境の単環境だけで3ヶ月+バッファと考えるのが無難です。また、テスト環境と本番環境で環境差有りが現実です。キャッシュ実装は環境差に悩まされ、実装、パージ、warmup、計測、挙動確認/検証、のようにたった1アクションでも実装完了までに必要な工程や時間が長いです。本番環境の承認会議では、テスト環境と本番環境で環境差が有るため、運用に支障をきたさない範囲で実装の実行と撤退を繰り返しながらPDCAを回す旨をあらかじめ宣言すると良いです。本番環境は、設計や運用ドキュメントも作成しながら別の3ヶ月とすることが推奨されます。
キャッシュヒット率を初回訪問から爆上げするソリューションを開発しました
👉️キャッシュHit率を初回訪問から爆上げ「高精度CacheWarm&Checker Nissy」モニター募集
