PageSpeed Insights がすべてエラーになる原因と解決方法

PageSpeed Insights がすべてエラーになる原因と解決方法

opacity: 0 が引き起こす LCP 判定不能問題

はじめに

PageSpeed Insights を実行したところ、スコアが表示されず、LCP / CLS / TBT など すべての指標がエラー表示 になる状況に遭遇しました。

サーバ設定や JavaScript、Google Fonts、GTM などを疑っても原因が分からず、最終的に CSS の opacity: 0 が原因 だったケースです。

この記事では、なぜ opacity: 0 が PageSpeed Insights の計測を妨げるのか、そして実務でどう修正すべきかを整理します。

問題の症状

PageSpeed Insights での表示

  • すべての指標が「Error!」表示になる
  • LCP(Largest Contentful Paint)が取得できない
  • スコアが計測不能

    実際のブラウザでの表示

一方で、実ブラウザでは次のように見えます。

  • 表示は正常
  • ファーストビューも問題なく表示される
  • フェードイン演出も意図通り動作する

この「PSI では失敗するのに、見た目は正常」という乖離が、原因特定を難しくします。

原因:LCP 要素が opacity: 0 になっていた

結論から言うと、Largest Contentful Paint(LCP)の要素が初期描画時に opacity: 0 だったことが原因です。

LCP の判定ルール

LCP は「ユーザーに実際に表示されている最大要素」を計測します。

そのため、以下の状態の要素は LCP から除外されます。

  • opacity: 0
  • visibility: hidden
  • display: none
  • その他、視覚的に不可視な状態

初期描画時に LCP 要素が不可視だと、LCP が確定できず、結果として スコア算出ができない(多くの指標が「—」や Error になる) ことがあります。

よくある実装パターン(アンチパターン)

.hero {
  opacity: 0;
  transition: opacity 0.8s ease;
}

.hero.is-visible {
  opacity: 1;
}
window.addEventListener('load', () => {
  document.querySelector('.hero').classList.add('is-visible');
});

人間の目では問題ない理由

  • load イベント後すぐにフェードインする
  • 体感では最初から表示されているように見える

PageSpeed Insights / Lighthouse での挙動

  • 初期描画時点で「表示されていない」と判断される
  • LCP が確定できず、NO_LCP 扱いになる
  • スコア計算ができず、指標が Error / 「—」表示になる

結果として、PageSpeed Insights がすべてエラー表示という状態になります。

実際に発生したケース

本サイトで実際に発生した事例です(再現性のある形で確認できました)。

修正前のコード

.hero {
  opacity: 0;
  transition: opacity 0.8s ease;
}

PageSpeed Insights の結果:

  • First Contentful Paint: Error!
  • Largest Contentful Paint: Error!
  • すべての指標が計測不能

試した修正①:opacity を 0.01 にする

.hero {
  opacity: 0.01;
  transition: opacity 0.8s ease;
}

結果:すべての指標が正常に計測されるようになりました。

この結果から、opacity: 0(完全なゼロ)が「不可視」判定の閾値になっている可能性が高いと分かりました。視覚的にはほぼ不可視でも、技術的には「可視」扱いとなり、LCP として認識されます。

推奨される最終的な修正

.hero {
  opacity: 1; /* アニメーションは削除 */
}

opacity: 0.01 で解決することは確認できましたが、これは回避策です。ファーストビューやメインビジュアルなど、LCP になり得る要素は、初期表示で必ず可視にすることが重要です。

解決方法

基本:LCP 要素では opacity: 0 を使わない

最も確実な方法です。

.hero {
  opacity: 1; /* 初期表示は必ず可視 */
}

ファーストビューやメインビジュアル、h1 など、LCP になり得る要素は必ず初期表示で可視にすることが重要です。

代替案:どうしてもアニメーションが必要な場合

視覚的な演出が必須の場合:

.hero {
  opacity: 0.01; /* 視覚的にはほぼ不可視だが、LCP 判定は通過 */
  transition: opacity 0.8s ease;
}

注意: これは回避策です。可能なら、LCP になり得る要素は初期表示で opacity: 1 にしてください。

ファーストビュー外でのみアニメーションを使う

/* ファーストビューではアニメーションを使わない */
.hero {
  opacity: 1;
}

/* スクロール後に表示される要素のみアニメーション */
.section:not(:first-child) .content {
  opacity: 0;
  transition: opacity 0.8s ease;
}

.section:not(:first-child) .content.is-visible {
  opacity: 1;
}

確認方法

Chrome DevTools での確認(推奨)

  1. DevTools を開く(F12)
  2. Lighthouse タブを選択
  3. Mobile を選択
  4. Analyze page load(または同等の実行ボタン)を実行
  5. LCP の数値が表示されるか確認

LCP が「Error!」または「—」表示の場合、LCP 要素が正しく認識されていません。

Performance パネルで LCP 要素を特定

  1. DevTools → Performance タブ
  2. リロードして記録
  3. Timings セクションで「LCP」を確認
  4. クリックすると該当要素がハイライト表示される

この方法で、どの要素が LCP として認識されているか(または認識されていないか)を確認できます。

まとめ

  • PageSpeed Insights がすべてエラーになる原因は CSS の opacity: 0
  • LCP 要素が不可視だと LCP が確定できず、スコア算出ができない
  • サーバや JavaScript が正常でも発生する
  • 解決策は LCP 要素を初期表示で可視にすること
  • opacity: 0.01 で回避できる場合はあるが、本質的には初期表示で可視にするのが安全

これはフロントエンド実装における典型的な落とし穴です。

Google Fonts や GTM、サーバ設定を疑ってしまいがちですが、原因は CSS 1 行というケースもあります。同様の症状で悩んでいる場合は、まず opacityvisibility の指定を確認してみてください。