2-1 Core Web Vitals を Claude Code で改善する
無料LCP / INP / CLS の意味と Good 境界値を理解し、PageSpeed Insights と Claude Code で実測。表示速度の遅さの原因と定番の打ち手をセットで身につける Core Web Vitals 改善ガイド。
このレッスンで身につくこと
Google がページの「速さ」「使いやすさ」をどう数値化しているか — その正体 Core Web Vitals を、自分のサイトを測って・読み解いて・改善する ところまで掘り下げます。
このレッスンのゴール
- LCP / INP / CLS の 3 指標が何を測っているか、自分の言葉で説明できる
- それぞれの「Good / Needs improvement / Poor」の境界値を覚える
- Claude Code + PageSpeed Insights + Lighthouse で実測する手順を体に入れる
- 各指標で「典型的な遅さの原因」と「定番の打ち手」をセットで持つ
- 過剰最適化 や 計測環境のばらつき という落とし穴を避けられる
所要時間 約 45 分 難易度 ★★☆☆☆(HTML / CSS の基本が分かれば OK)
ページの「速さ」が検索順位に直結する理由
Google の調査では、表示に 3 秒以上かかるとユーザーの 半数以上が離脱、5 秒を超えると 90% に跳ね上がります。遅いサイトばかり並んでいたら Google 自体が信用を失う — だから Google は「速くて・操作しやすくて・表示がガタつかないサイト」を優遇する仕組みをアルゴリズムに組み込みました。それが Core Web Vitals です。
検索順位は「コンテンツの質」と「ページ体験の質」の掛け算。コンテンツ 8 割・体験 2 割 の感覚で押さえる。良い記事でも遅ければ沈み、薄い内容でも体験が良ければ競合より上に出ることがあります。
Core Web Vitals は 読み込みの速さ 操作の応答性 表示の安定性 の 3 軸を、それぞれ 1 指標で代表させています。
| 指標 | フルネーム | 何を測るか |
|---|---|---|
| LCP | Largest Contentful Paint | ページの「主役」が表示されるまでの時間 |
| INP | Interaction to Next Paint | クリックやタップに対する反応の速さ |
| CLS | Cumulative Layout Shift | 読み込み中に画面がガタつく量 |
3 指標は独立評価。1 つだけ良くても全体評価は上がらない。3 つすべて Good ゾーンを目指します。
3 つの指標を身近な例えで理解する
ここでは レストラン に例えて、3 つの指標を体に入れていきます。
LCP(表示速度)— 料理が出てくるまでの時間
注文してからメインが運ばれてくるまで何分かかるか?これが LCP です。Web では「ページの中で一番大きな要素(メイン画像・見出し・記事冒頭)が表示されるまでの時間」を測ります。ユーザーが「ページが表示された」と認識する瞬間 をミリ秒で記録しています。
| 評価 | しきい値 | 体感 |
|---|---|---|
| Good | 2.5 秒以内 | サクッと表示された |
| Needs improvement | 2.5〜4.0 秒 | ちょっと待たされた |
| Poor | 4.0 秒超 | 「遅い、戻る」と思われる |
LCP の対象は、たいていヒーロー画像 / <h1> / ファーストビューの段落 / 動画の最初のフレーム のいずれか。サーバー応答 + リソース取得 + レンダリング の 3 段階で構成されます。
INP(操作の応答速度)— 店員さんの反応の速さ
「すみません」と呼んで、すぐ振り返ってくれるか?これが INP の世界観です。クリック・タップ・キー入力に対して、次の描画が走るまでの遅延を測ります。
| 評価 | しきい値 | 体感 |
|---|---|---|
| Good | 200 ミリ秒以内 | 押した瞬間に反応 |
| Needs improvement | 200〜500 ミリ秒 | ワンテンポ遅い |
| Poor | 500 ミリ秒超 | 押せてないのでは?と二度押し |
INP は 2024 年 3 月に FID を置き換えました。FID は「最初の 1 回」だけだったのに対し、INP は 訪問中の全操作の中で最悪値に近いもの を見るので、ぐっと現実的です。
INP は最近のサイトで最も見落とされやすい指標です。LCP と CLS が Good でも INP だけ Poor、というサイトは 驚くほど多い。重い React / Vue アプリ、大量の外部タグ、サードパーティチャットボットが定番の犯人。
CLS(表示のズレ)— テーブルの上で皿が勝手に動く
食事中に皿が勝手にズレたら困ります。Web でも読んでいる途中で要素が ガクッとずれる ことがある。「ボタンを押そうとした瞬間に広告が差し込まれて、押すつもりのない広告を踏まされた」— こういう体験を数値化したのが CLS です。
| 評価 | しきい値 | 体感 |
|---|---|---|
| Good | 0.1 以下 | ズレを感じない |
| Needs improvement | 0.1〜0.25 | たまにズレる |
| Poor | 0.25 超 | 読みづらい・誤タップ多発 |
CLS は秒ではなく スコア。「画面のどれくらいの面積が・どれくらいの距離ズレたか」を掛け合わせた値。「1 ページ読む間に画面の 1/10 がガクッと動いたら Poor 寄り」 と覚えると感覚をつかみやすい。
なぜ SEO 順位に影響するのか
Core Web Vitals は Page Experience(ページ体験) カテゴリの中核。Google は「コンテンツの質」を最優先するので、質が大きく違うページが並ぶとき Core Web Vitals だけで逆転することはほぼありません。でも コンテンツが同じくらいのページが 3 つ並ぶ とき、Page Experience が最後のタイブレーカーとして効いてきます。
Core Web Vitals は、勝つための武器ではなく、負けないための盾。極限まで速くする必要はない。でも競合より明らかに遅いと、コンテンツが互角でも下に沈みます。「Good ゾーンに入れる」だけ で十分。
ラボデータとフィールドデータの違い
2 種類のデータ があります。
- ラボデータ — Lighthouse などが決まった環境で 1 回測った値。再現性は高い
- フィールドデータ — 実ユーザー訪問を Google が CrUX(Chrome User Experience Report) として集めた値。PageSpeed Insights の上半分に出るのがこれ
Google が SEO 評価に使うのはフィールド。Lighthouse 100 点でもフィールドが Poor なら SEO 上は Poor 扱い。開発中はラボ、本番判断はフィールド、と使い分けます。
Claude Code で実測する手順
Claude Code は PageSpeed Insights API や Lighthouse を内部で呼べるので、URL を渡すだけで Core Web Vitals を取ってきます。
手順 1 — Claude Code で一発診断
$ claude
> /seo technical https://your-site.com
# 内部処理:
# 1. PageSpeed Insights API でフィールド + ラボデータを取得
# 2. Lighthouse の結果から各指標を抽出
# 3. しきい値と比較して判定
# 4. 改善案を優先度付きで提示実行結果の例。
─── Core Web Vitals (Field data, 28 days) ───
LCP: 3.2s ⚠ Needs improvement
INP: 180ms ✅ Good
CLS: 0.18 ⚠ Needs improvement
─── 改善の優先度 ───
1. [HIGH] LCP: hero.jpg (2.1MB) が大きすぎる
→ WebP 化 + width/height 指定で 0.8 秒短縮見込み
2. [MID] CLS: フォント読み込み時に見出しがズレている
→ font-display: optional または preload で改善「この改善を適用して」と返事すれば、Claude が 実際にコードを書き換えて くれます。
手順 2 — PageSpeed Insights で答え合わせ
Claude の出力を鵜呑みにせず、自分の目でも一次情報を確認 しましょう。https://pagespeed.web.dev/ で URL を入力するだけ。見るべきは 画面上部の 4 つの数字、「実際のユーザー環境で評価」 セクション(フィールド、SEO 影響あり)、「パフォーマンスの問題を診断」 セクション(ラボ、改善のヒント)の 3 箇所です。
PageSpeed Insights は 1 日数回 のレートリミットあり。連続して叩くと「データを取得できません」になるので、本気で測るときは Claude Code 経由が安定です。
手順 3 — Lighthouse をローカルで回す
Chrome DevTools の Lighthouse タブが便利。F12 → Lighthouse → Mobile / Performance のみ → Analyze。シークレットウィンドウ で実行すれば拡張機能の影響を消せます。CI に組み込むなら npm install -g lighthouse で CLI 版。
手順 4 — Search Console で長期トレンドを追う
Search Console の「ウェブに関する主な指標」レポートを月 1 で確認。URL グループ単位 で「商品ページだけ遅い」「ブログだけ CLS が悪い」というパターンが浮き彫りになります。「不良」グループを Claude Code に渡して /seo technical で深掘り、というのが定番フローです。
LCP を改善する定番パターン
全部やる必要はありません。Claude Code が「これが効く」と指摘したものから、優先度順に潰します。
パターン 1 — ヒーロー画像を WebP / AVIF にする
LCP の原因が 画像 であることは本当に多い。4000×3000px の元画像を 200×150px の領域に流し込んでいる、というパターンが現場で頻発します。
<!-- Before -->
<img src="hero.jpg" alt="サービス紹介">
<!-- After -->
<img src="hero.webp" alt="サービス紹介"
width="1200" height="630"
fetchpriority="high" decoding="async">- WebP は JPG より 30% 軽い、AVIF はさらに 50% 軽い
- width / height 属性 でブラウザが領域を確保(CLS にも効く)
- ==fetchpriority="high"== でヒーロー画像を優先ダウンロード
- ファーストビューの画像に
loading="lazy"を付けない — LCP が悪化 する典型事故
よくある事故 — 「全画像を一律 loading="lazy"」と決めてヒーロー画像まで lazy を付ける。Lazy loading は ファーストビュー外 にだけ。
パターン 2 — フォントを preload + font-display: swap
Web フォントは LCP の隠れた原因。読み込み完了を待ってから描画する設定(FOIT)だと、見出しが 1〜2 秒遅れます。
<link rel="preload" href="/fonts/NotoSansJP-Regular.woff2"
as="font" type="font/woff2" crossorigin>@font-face {
font-family: 'Noto Sans JP';
src: url('/fonts/NotoSansJP-Regular.woff2') format('woff2');
font-display: swap;
}font-display: swap でテキストが一瞬で見えるので LCP が大幅改善します。
パターン 3 — TTFB(サーバー応答時間)を縮める
TTFB は LCP の上限。サーバーが最初のバイトを返すまでの時間が長いと、その後どんなに頑張っても LCP は短くなりません。
| TTFB の原因 | 打ち手 |
|---|---|
| 遅いクエリ | インデックス追加、N+1 解消、キャッシュ |
| 外部 API への直列呼び出し | 並列化、結果キャッシュ |
| サーバーが地理的に遠い | CDN でエッジ配信 |
| 重い SSR 同期処理 | ストリーミング SSR、Edge Runtime |
Cloud Run / Vercel ユーザー向け
Cloud Run は コールドスタート が TTFB を直撃。min-instances >= 1 か、CPU を「常時割り当て」にすると最初のリクエストでも数十 ms で返せます。
パターン 4 — Critical CSS をインライン化
外部 CSS の読み込み待ちも LCP を遅らせる原因。ファーストビューに必要な CSS だけ を <style> で HTML に埋め込み、残りは非同期で読み込みます。Next.js / Astro / Remix などでは 自動抽出 されることが多い。
INP を改善する定番パターン
INP は JavaScript の重さ がほぼ全ての原因。打ち手は「JS を減らす / 分割する / 遅らせる」のいずれかに集約されます。
パターン 1 — 重い処理を次のフレームに逃がす
ボタンクリックで 500ms 級の同期処理を走らせると、INP は確実に Poor。ユーザーが見たいのは結果ではなく「押せた」というフィードバック。まずローディング表示を出し、重い処理は次のフレームに逃がします。
// After — UI 反応を先に返す
button.addEventListener('click', () => {
showLoading();
requestIdleCallback(() => {
const result = heavyCalculation();
showResult(result);
});
});パターン 2 — サードパーティスクリプトを defer
INP を悪化させる隠れた巨人が、Google Analytics / Meta Pixel / チャット / ヒートマップなどの サードパーティタグ。<head> に同期で並べるとユーザー操作中もバックグラウンドで CPU を奪い続けます。
<script src="https://cdn.example.com/tracker.js" defer></script>Partytown を使えばサードパーティスクリプトを Web Worker で動かせ、メインスレッドへの影響を限りなくゼロにできます。
パターン 3 — 巨大な JS バンドルをコード分割
SPA で初回 1MB 超の JS を全部読み込むサイトは INP がほぼ確実に悪化。ルート単位 / コンポーネント単位 で分割し、必要なときだけ読み込む。React なら lazy + Suspense、Vue なら defineAsyncComponent、Next.js なら next/dynamic が標準手段です。
CLS を改善する定番パターン
CLS は 画面領域が事前に確保されていない ことが原因。「あとから入ってくる要素」のサイズを HTML / CSS の段階で予約しておけば、ほとんど解決します。
パターン 1 — 画像・動画・iframe に width / height を必ず指定
これだけで CLS が 0.05 縮むことも普通にあります。
<!-- Bad -->
<img src="photo.jpg" alt="商品写真">
<!-- Good -->
<img src="photo.jpg" alt="商品写真" width="800" height="600">レスポンシブ対応は CSS で width: 100%; height: auto; を当てつつ、HTML 属性でアスペクト比をブラウザに伝えます。
パターン 2 — 広告枠を min-height で予約
Google AdSense や記事内広告は、読み込み完了時に 突然挿入されてレイアウトを破壊 します。親要素に min-height を設定し、広告が来ても来なくても領域が変わらないようにする。
.ad-slot { min-height: 250px; background: #f5f5f5; }パターン 3 — フォント差し替えの「ガクッ」を抑える
font-display: swap で LCP は改善しますが、システム → Web フォント に差し替わる瞬間に文字幅が変わって CLS にカウントされることがあります。==size-adjust / ascent-override== でフォントメトリクスを揃えれば、差し替え時のズレをほぼゼロにできます。Claude Code に「Web フォントの size-adjust を計算して」と頼むと fontaine などで自動算出してくれます。
失敗パターン — 過剰最適化 と 計測環境のばらつき
「やった方がいい」打ち手を並べてきましたが、やりすぎ もまた SEO の敵です。
罠 1 — Lighthouse 100 点を取ろうとして本来の機能を削る
過剰最適化の典型例
- 全画像を極端に圧縮して画質がガビガビになる
- アニメーションを削除して操作感が冷たくなる
- フォントをシステムフォントに差し戻してブランドが崩れる
- 必要な分析タグまで削って、データドリブンな改善ができない
Good ゾーンに収まれば SEO 上は同等扱い。LCP 1.2 秒と 2.4 秒に SEO 的な差は基本ない。Good に入ったら止めて、コンテンツ改善に時間を使う方がリターンは大きい。
罠 2 — 1 回の測定結果で一喜一憂する
ラボデータは計測のたびに 15〜30% は揺れます。同じページを Lighthouse で 5 回測ると LCP が 1.8 / 2.3 / 2.0 / 2.6 / 1.9 秒、は普通。CPU 負荷・ネットワーク・キャッシュで微妙にズレるためです。5 回測って中央値 / Before / After は同じ環境 を守れば惑わされません。
フィールドデータ は 28 日集約で揺らぎが小さい。本番判断はフィールド、開発判断はラボ中央値、と使い分けます。
罠 3 — ローカル開発の Lighthouse を信じる
MacBook Pro の Lighthouse は 現実のユーザーが体感する速度より速い。CPU は平均的なスマホの 3〜5 倍、開発時はキャッシュが効きやすく、自宅 Wi-Fi は 4G より速いから。Lighthouse の Mobile / 4x slowdown、DevTools の CPU throttling を必ず使う。実機の Android 中位機種で測る のが最も正直です。
計測は「平均的なユーザー」を想定するゲーム。開発者の手元(高性能 PC + 高速回線)で測ると、ユーザーが体感する遅さの 1/3 くらいしか感じられません。フィールド Poor / ラボ Good のギャップに気づいたら、ほぼ「計測環境が現実より良すぎる」サインです。
まとめと演習
まとめ
- Core Web Vitals は LCP(読み込み) INP(操作応答) CLS(表示の安定) の 3 指標
- 目標は LCP ≤ 2.5 秒 / INP ≤ 200ms / CLS ≤ 0.1。3 つすべて Good を目指す
- SEO 評価には フィールドデータ(実ユーザー 28 日)。ラボは開発時の検証用
- 改善は Claude Code → PageSpeed Insights → Lighthouse → Search Console の順で深掘り
- LCP は 画像 / フォント / TTFB、INP は JS の重さ、CLS は 領域確保 と原因の住み分け
- 過剰最適化と計測ばらつき は最大の落とし穴。Good に入ったら立ち止まる
章末演習 — 手元のサイトで次を試してください。所要時間 20〜30 分。
- PageSpeed Insights でモバイル / デスクトップを測定し、3 指標の現状をメモする
- Claude Code で
/seo technicalを実行し、改善案リストを取得する - 改善案の中で 一番効きそうなもの 1 つだけ を選び、選んだ理由を 1 行で書き残す
- その改善を適用し、再測定で数値の変化を確認する
- (余裕があれば)Search Console で URL グループ単位の傾向を眺める
「1 つの改善で 1 つの数値が動く」 という体験を、まず 1 回しておくことが大事です。
<Checklist id="cwv-self-check" items={["LCP / INP / CLS が何を測っているか、自分の言葉で説明できる","それぞれの Good しきい値(2.5 秒 / 200ms / 0.1)を覚えた","ラボデータとフィールドデータの違いを理解した","Claude Code の /seo technical コマンドで実測した","改善パターンを最低 1 つ自分のサイトに適用した"]} />
<Quiz question="Core Web Vitals の LCP の目標値は?" options={["2.5秒以内","5秒以内","1秒以内"]} answer={0} />
<Quiz question="Google が SEO 評価に使うのは次のどちらですか?" options={["実ユーザーから集めたフィールドデータ(CrUX)","Lighthouse をローカルで実行したラボデータ","両方を平均した値"]} answer={0} />
<Quiz question="INP を悪化させる最大の原因は次のうちどれ?" options={["重い JavaScript の同期実行","画像のファイルサイズ","CSS の量"]} answer={0} />
次のレッスン 2-2: robots.txt とサイトマップ では、Google のクローラーに「どのページを見てほしいか」を正確に伝える方法を学びます。