Lighthouse ExporterとGrafanaによるCore Web Vitals監視の自動化:本番運用6ヶ月の知見

Monitoring tutorial - IT technology blog
Monitoring tutorial - IT technology blog

なぜサーバー監視だけでは不十分なのか?

Eコマースプロジェクトでモニタリングシステムを半年以上運用した結果、一つの手痛い教訓を得ました。PrometheusのダッシュボードではサーバーのCPU/RAM使用率が非常に低く、各サービスは「正常(グリーン)」と表示されているにもかかわらず、ユーザーからは「トップページの表示に8秒もかかる」という不満が寄せられていたのです。問題は、バックエンドのインフラに集中しすぎて、ブラウザ上での実際のユーザー体験(RUM)を見落としていたことにありました。

GoogleはCore Web Vitalsという指標セットを使ってWebサイトを評価します。SEOに携わっている方なら、これらの指標が検索結果の1ページ目に表示されるか10ページ目に沈むかを左右することをご存知でしょう。しかし、毎日手動でChrome DevToolsを開いてチェックするのは不可能です。そこで、ウェブサイト・API自動監視を強化するため、Lighthouse Exporterを監視フローに導入しました。このツールは、Lighthouse의無機質なレポートをGrafana上のリアルタイムデータに変換してくれます。

Lighthouse Exporterの仕組み

Lighthouse Exporterは通常、Dockerコンテナとして動作します。実行されると、ヘッドレスブラウザ(headless Chrome)を起動して設定したURLにアクセスします。スキャン完了後、その結果をPrometheusが理解できるメトリクス形式に変換します。

私が日常的に監視している「ゴールデンメトリクス」は以下の通りです:

  • Largest Contentful Paint (LCP): 最大のコンテンツ(通常はバナーや商品画像)の読み込み速度を測定します。
  • Cumulative Layout Shift (CLS): 画像の読み込み中などにレイアウトがガタガタと崩れないかを確認します。
  • Total Blocking Time (TBT): 重いJavaScript의処理によってブラウザがフリーズしている時間を測定します。
  • Performance Score: 上司やクライアントへの報告に便利な総合スコアです。

最大の利点は、Exporterが固定されたサーバー上で動作することです。これにより、開発者のWi-Fi環境や個人のPCスペックといったノイズが排除され、常に一貫性のある測定データが得られます。

実践:Core Web Vitals監視システムの構築

開始する前に、PrometheusとGrafanaの環境が整っていることを確認してください。まだの場合は、私のブログにある基本的なインストールガイドを5分でおさらいしておきましょう。

ステップ1:DockerでLighthouse Exporterを起動する

Dockerを使用するのが最も手軽なデプロイ方法です。注意点として、Headless Chromeはリソースを大量に消費します。他のサービスに影響を与えないよう、コンテナのRAM制限を設定することをお勧めします。

docker run -d \
  --name lighthouse-exporter \
  -p 9242:9242 \
  --memory="1g" \
  -e "LIGHTHOUSE_SCRAPE_INTERVAL=300" \
  -e "LIGHTHOUSE_TARGET_URLS=https://itfromzero.com,https://google.com" \
  --restart always \
  femtopixel/google-lighthouse-exporter

上記のコマンドでは、5分ごとに2つのWebサイトをスキャンするように設定しています。カンマ区切りで複数のURLを追加可能です。

ステップ2:Prometheusのデータ収集設定

次に、Prometheusにメトリクスの取得先を教えます。prometheus.ymlファイルを開き、以下の設定を追加します。

scrape_configs:
  - job_name: 'lighthouse-monitor'
    scrape_interval: 15m # スキャン頻度が高すぎるとサーバーがハングアップします
    static_configs:
      - targets: ['localhost:9242']

実務上の経験から、scrape_intervalを短くしすぎないことをお勧めします。Lighthouseの実行には1URLあたり約30〜60秒かかります。10個のURLを毎分スキャンし続けると、サーバーのCPUは常に過負荷状態になってしまいます。

ステップ3:Grafanaダッシュボードでの可視化

Prometheusがデータを受信し始めたら、あとはグラフを描くだけです。Grafana LabsにあるDashboard ID 12154 を使えば、素早くインポートできます。便利なPromQLクエリの例をいくつか紹介します:

  • パフォーマンススコアの監視: lighthouse_performance_score{url="https://itfromzero.com"}
  • LCPの監視(秒): lighthouse_lcp_seconds{url="https://itfromzero.com"}

現場の教訓:アラート疲れとリソース管理の対策

導入当初の最大の失敗は、パフォーマンススコアが80を下回った瞬間にアラートを飛ばす設定にしたことでした。その結果、国際回線の不安定さやサーバーのわずかなラグのたびに、スマホに通知が鳴り止まなくなりました。これがいわゆるアラート疲れ(Alert Fatigue)です。

対策として、30分間の平均値を計算する avg_over_time 関数を使用するように変更しました。30分間の平均スコアが低いままの場合にのみ、コードやインフラに本当の問題があると判断して通知するようにしたのです。これにより、不要なアラートの約90%を削減できました。

ハードウェアに関しては、Headless Chromeが非常に多くのCPUとメモリを浪費することを忘れないでください。1つのインスタンスで、サイトの重さに応じて500MBから1GBのRAMを消費します。以前、メインアプリケーションと同じ小型VPS(RAM 2GB)でExporterを動かした際、Webアプリごとダウンさせてしまったことがあります。

まとめ

Core Web Vitalsの監視は、単なる無機質な数値の羅列ではありません。ユーザーが実際にどのような体験をしているかを理解するための鍵です. Grafanaと組み合わせることで、「昨日のコード更新でサイトが遅くなっていないか?」「新しくアップロードした画像がレイアウト崩れの原因になっていないか?」といった傾向が一目でわかります。

ユーザーから苦情が来る前にグラフの異常を察知できることは、DevOpsエンジニアにとって大きな安心感に繋がります。SEO最適化が必要なWebサイトを管理しているなら、ぜひ今日からこの構成を試してみてください。

Share: