Core Web Vitalsガバナンス:LCP/CLS/INP 継続監視・回帰防止パイプライン完全設計
サイト速度を“継続的に”高水準へ保つ鍵は ガバナンス(運用標準化)。単発チューニングではなく、SLI/SLO → 計測 → 分布監視 → 逸脱検知 → トリアージ → 是正 → 学習フィードバック のループを自動化し、回帰を即時検知・修正する仕組みが必要です。本稿は LCP / CLS / INP の 3 指標を対象に、属性設計・収集・可視化・通知・是正フロー・ガードレールまで “壊れにくい” パイプラインをゼロから構築する完全ガイドです。
要点(TL;DR)
- P75 SLI(LCP/CLS/INP)を日次トレンド + 分布ヒートマップで監視。
- SLO: LCP < 2.4s / CLS < 0.1 / INP < 200ms (P75) を四半期単位で合意。
- 属性拡張: LCP要素分類 / naturalWidth / 形式 / preload有無, CLS原因セレクタ, INPイベント種別。
- 逸脱検知: (P75 3日平均 - 前4週移動中央値) > 閾値 で Slack / OpsGenie 通知。
- トリアージSLA: 重大(P75閾値超過継続) 24h / 中度 3d / 軽度 次スプリント。
- Fix後は リリース前ラボ計測 + RUM diff を自動コメント。
背景(Why)— 単発最適化が失敗する理由
一度改善した CWV が数週で悪化する典型原因は (1) 新機能の画像/JS 負荷増が無監視, (2) 広告・A/Bテストが寸法/優先度を乱す, (3) キャッシュ/プリロードが形骸化, (4) 計測粒度が平均のみで回帰が埋没 の 4 つです。分布と属性を持たない指標は“原因特定コスト”が高く、是正が遅れ結果的に UX と検索トラフィック損失を生みます。
- 平均/単一値監視 → 外れ値/端末条件に引き摺られ意思決定が曖昧。
- 手動レポート → 属人化・遅延。週次収集では異常検知が数日遅れる。
- 属性不足 → LCP劣化の“どの画像”か特定不能で仮説探索に時間。
1. 指標 (SLI) と SLO の設計
SLI はユーザ体験を直接代表する P75 LCP/CLS/INP。SLO は四半期末時点で “P75 LCP < 2.4s / CLS < 0.1 / INP < 200ms” の達成率 95% を目標。内部用 KPI と検索影響を意識し ガードバンド (例: LCP 2.2s) を設け早期是正領域を確保します。
2. 計測実装(RUM + ラボ二層構成)
RUM は web-vitals
+ navigator.sendBeacon
で JSON を送信し、Snowflake / BigQuery / ClickHouse 等へ収集。ラボは Lighthouse CI (3G Fast / MotoG4) + WebPageTest API (実機/地域差) の二層。リリース毎にラボトレンド, 日次に RUM 分布を可視化し回帰方向を早期発見。
- サンプリング:
Math.random() < 0.2
(20%) など動的変更可能。 - 最小ペイロード: metric名, value, id, navigationType, device(UA軽量判定), conn.effectiveType。
- バッチ送信: VisibilityChange でキュー flush。失敗時 localStorage リトライ。
3. 属性スキーマ設計(原因特定の高速化)
各 metric に以下の拡張属性を付与し、“回帰=特定” までの時間を短縮:
LCP 拡張
- elementType(img|image|text)
- naturalWidth / naturalHeight
- mime(webp|jpeg|png|avif|other)
- preload(has|none)
- priority(hint|auto)
CLS 拡張
- shiftCount
- largestShift
- sources(広告|画像|フォント|DOM挿入)
- layoutShiftSelectors[3]
INP 拡張
- eventType(click|keydown|pointerdown|custom)
- processing / presentation / duration 内訳
- longTaskCount(before/after)
- mainThreadBlock(ms)
4. ダッシュボード(可視化テンプレ)
役割別に “判断に必要な最小チャート” を分割。経営層=四半期 SLO 達成率、開発=日次 P75 推移 + 分布、SRE=逸脱インシデント一覧。
- 分布ヒートマップ: LCP 0〜6s を 200ms ビン、INP 0〜600ms を 20ms ビン。
- 変動検知: 4週移動中央値 と 現在3日移動平均の差分。
- 寄与分析: LCP上位遅延要素 Top20 (画像URLハッシュ)。
- リリースオーバーレイ: デプロイ SHA を垂直ライン。回帰との関連付け高速化。
5. 逸脱検知と通知ルール
単純閾値 + 統計的手法 (EWMACUSUM 等) を併用し 過剰通知/Fatigue を防止。
- SLO逸脱: 3日移動平均 P75 LCP ≥ 2.4s が連続2日 → High。
- 急激劣化: (今日P75 - 直近7日中央値)/中央値 ≥ 0.15 → Medium。
- CLSスパイク: 1ページで CLS≥0.25 の割合が週平均比 +50% → Medium。
- INP悪化: P75 INP ≥ 220ms かつ longTaskCount 上昇 → High。
6. トリアージ & 是正フロー
通知後は “分類→仮説→再現→Fix PR→検証→クローズ” の 6 ステップを 24h 内に開始。テンプレで情報欠損を防止。
分類
- 画像系 (解像度/優先度)
- JS (長タスク)
- 広告/実験
- レイアウト (寸法漏れ)
仮説/再現
- 該当URLで PerformanceTimeline
- LayoutShift API ログ
- Long Task attribution
Fix PR
- 原因タグ差分
- Before/After ラボ計測
- 想定改善幅 (ms)
7. ガードレール(回帰予防の自動化)
- PR Lint: 無寸法
<img>
を拒否。画像タグ差分で naturalWidth 推定。 - preload棚卸しCI: link[rel=preload] 数と対象を静的解析し 1 枚超過で警告。
- Long Task Budget: build後 bundle breakdown で 50ms 以上関数を列挙。
- 広告高さ検査: AdSlot が min-height 指定か AST/型チェック。
公開前/運用チェックリスト
- SLI/SLO ドキュメント化 (Confluence/README)
- web-vitals + 属性拡張 送信実装済
- ダッシュボード: 分布 / P75 推移 / リリースオーバーレイ
- 逸脱検知ルール Slack 通知動作確認
- トリアージ PR テンプレ (原因/計測/改善予測) 適用
- ガードCI: 無寸法 img / preload過多 / long task budget / AdSlot高さ
- 四半期レビュー用レポート自動生成スクリプト
FAQ(抜粋)
- P75 が安定しない: 端末/ネットワーク mix 変化。device / effectiveType 別分割を追加。
- INP がランダム悪化: 遅延画像 decode + 入力イベント重畳。初回スクロール閾値縮小と decode 遅延制御。
- CLS 原因が不明: LayoutShift API の sources を収集していない。API 対応ブラウザでセレクタ抽出。
まとめ(価値 & 次アクション)
CWV 改善は一度きりではなく “回帰し続ける敵” との継続戦。SLI/SLO / 属性 / 分布 / ガードレール を最小構成で導入することで、発生→検知→是正 を機械的ループへ落とし込み、UX / SEO / 収益を守る“パフォーマンスオペレーション”を確立できます。次のアクションは (1) SLO 草案合意 (2) 計測ペイロード拡張 (3) ダッシュボード MVP 作成 の 3 つです。