Core Web Vitals完全ガイド2026 - ページエクスペリエンス最適化
LCP、INP、CLS指標の意味と最適化方法。Googleランキング要因であるCore Web Vitalsを改善する実践ガイド。
Toolypet Team
Development Team
Core Web Vitals完全ガイド2026
「サイトが遅かったから離脱した」
53%のユーザーは、読み込みに3秒以上かかるとページを離れます。Googleはこのユーザーエクスペリエンスをランキングに反映するためにCore Web Vitalsを導入しました。
2026年現在、Core Web VitalsはモバイルSEOの重要なランキング要因です。
Core Web Vitalsとは?
Core Web Vitalsは、ユーザーエクスペリエンスを測定する3つの主要指標です。
2026年の指標
| 指標 | 測定項目 | 良好 | 改善が必要 | 不良 |
|---|---|---|---|---|
| LCP | 読み込み速度 | ≤2.5秒 | ≤4秒 | >4秒 |
| INP | インタラクション応答 | ≤200ms | ≤500ms | >500ms |
| CLS | 視覚的安定性 | ≤0.1 | ≤0.25 | >0.25 |
指標の変更(2024年)
FID (First Input Delay) → INP (Interaction to Next Paint)
FID: 最初の入力のみ測定
INP: すべてのインタラクションの応答性を測定(より包括的)
LCP(Largest Contentful Paint)
定義
ページ上で最大のコンテンツ要素が画面にレンダリングされるまでの時間
測定対象
| 要素 | 例 |
|---|---|
<img> | ヒーロー画像 |
<video>ポスター | 動画サムネイル |
CSS background-image | 背景画像 |
| テキストブロック | <h1>、<p>など |
最適化方法
1. 画像最適化
<!-- ❌ 遅い -->
<img src="hero.png" alt="Hero">
<!-- ✅ 最適化 -->
<img
src="hero.webp"
srcset="hero-400.webp 400w, hero-800.webp 800w"
sizes="(max-width: 600px) 400px, 800px"
alt="Hero"
loading="eager"
fetchpriority="high"
>
2. サーバー応答時間(TTFB)
目標: TTFB < 200ms
改善方法:
- CDNの使用
- サーバーサイドキャッシング
- データベースクエリの最適化
- HTTP/2またはHTTP/3
3. レンダリングブロッキングリソースの除去
<!-- ❌ レンダリングブロッキング -->
<link rel="stylesheet" href="styles.css">
<script src="app.js"></script>
<!-- ✅ 最適化 -->
<link rel="stylesheet" href="critical.css">
<link rel="preload" href="styles.css" as="style" onload="this.rel='stylesheet'">
<script src="app.js" defer></script>
4. クリティカルCSSのインライン化
<head>
<style>
/* 初期画面に必要なCSSのみインライン */
.hero { ... }
.header { ... }
</style>
<link rel="preload" href="full.css" as="style">
</head>
5. プリロードヒント
<head>
<!-- LCP画像のプリロード -->
<link rel="preload" href="hero.webp" as="image" fetchpriority="high">
<!-- ウェブフォントのプリロード -->
<link rel="preload" href="font.woff2" as="font" crossorigin>
</head>
INP(Interaction to Next Paint)
定義
ユーザーインタラクション(クリック、タップ、キー入力)から次の画面更新までの時間
FIDとの違い
| FID | INP |
|---|---|
| 最初の入力のみ | すべてのインタラクション |
| 入力遅延のみ | 全体の応答時間 |
| 2024年廃止 | 2024年3月に置き換え |
測定対象
- クリック(マウス、タッチ)
- キー入力
- タップ(モバイル)
最適化方法
1. メインスレッドのブロッキング防止
// ❌ メインスレッドをブロック
function heavyTask() {
for (let i = 0; i < 1000000; i++) {
// 重い計算
}
}
// ✅ チャンクに分割
async function heavyTaskChunked() {
const chunks = splitIntoChunks(data, 1000);
for (const chunk of chunks) {
processChunk(chunk);
await new Promise(r => setTimeout(r, 0)); // 譲歩
}
}
2. デバウンス/スロットル
// ❌ 毎回実行
input.addEventListener('input', search);
// ✅ デバウンス
input.addEventListener('input', debounce(search, 300));
3. Web Workerの使用
// メインスレッド
const worker = new Worker('worker.js');
worker.postMessage(data);
worker.onmessage = (e) => updateUI(e.data);
// worker.js
self.onmessage = (e) => {
const result = heavyComputation(e.data);
self.postMessage(result);
};
4. イベントハンドラーの最適化
// ❌ 重いハンドラー
button.onclick = () => {
computeData(); // 重い
updateDOM(); // DOM操作
sendAnalytics(); // ネットワーク
};
// ✅ 非同期分離
button.onclick = async () => {
requestAnimationFrame(() => {
updateDOM(); // 素早いUI更新を先に
});
await computeDataAsync();
sendAnalytics(); // 後で
};
5. スクリプトサイズの削減
// コード分割
const Modal = React.lazy(() => import('./Modal'));
// ツリーシェイキング
import { specific } from 'library'; // フルインポートを避ける
CLS(Cumulative Layout Shift)
定義
ページ読み込み中の予期しないレイアウトシフトの累積スコア
問題シナリオ
ユーザー: ボタンをクリックしようとする瞬間
広告が読み込まれる: レイアウトがずれる
結果: 別のボタンをクリックしてしまう
最適化方法
1. 画像/動画のサイズ指定
<!-- ❌ サイズなし(CLSの原因) -->
<img src="photo.jpg" alt="Photo">
<!-- ✅ サイズ指定 -->
<img src="photo.jpg" alt="Photo" width="800" height="600">
<!-- ✅ aspect-ratioの使用 -->
<img src="photo.jpg" alt="Photo" style="aspect-ratio: 4/3; width: 100%;">
2. 広告/埋め込みのスペース予約
/* 広告領域を事前に予約 */
.ad-slot {
min-height: 250px;
background: #f0f0f0;
}
/* またはaspect-ratio */
.video-embed {
aspect-ratio: 16/9;
width: 100%;
}
3. ウェブフォント最適化
/* ❌ FOUT/FOITが発生 */
@font-face {
font-family: 'Custom';
src: url('font.woff2');
}
/* ✅ font-displayを使用 */
@font-face {
font-family: 'Custom';
src: url('font.woff2');
font-display: swap; /* またはoptional */
}
<!-- フォントのプリロード -->
<link rel="preload" href="font.woff2" as="font" crossorigin>
4. 動的コンテンツの処理
// ❌ 突然の挿入
container.innerHTML = newContent;
// ✅ スペースを予約してから挿入
container.style.minHeight = '200px';
container.innerHTML = newContent;
/* またはCSSで最小高さを設定 */
.dynamic-content {
min-height: 200px;
}
5. transformアニメーションの使用
/* ❌ レイアウトをトリガー */
.element {
animation: slide 0.3s;
}
@keyframes slide {
from { top: -100px; }
to { top: 0; }
}
/* ✅ transformを使用(レイアウトシフトなし) */
@keyframes slide {
from { transform: translateY(-100px); }
to { transform: translateY(0); }
}
測定ツール
フィールドデータ(実際のユーザー)
| ツール | データソース | 特徴 |
|---|---|---|
| Chrome UX Report | Chromeユーザー | 28日間の集計 |
| Search Console | CrUXベース | Google公式 |
| PageSpeed Insights | CrUX + Lighthouse | リアルタイム分析 |
ラボデータ(シミュレーション)
| ツール | 用途 |
|---|---|
| Lighthouse | Chrome DevTools内蔵 |
| WebPageTest | 詳細分析、比較テスト |
| GTmetrix | 視覚的なレポート |
Chrome DevTools
1. F12(開発者ツール)
2. Performanceタブ
3. Record → ページ更新
4. Web Vitalsセクションを確認
フレームワーク別最適化
Next.js
// next.config.js
module.exports = {
images: {
formats: ['image/avif', 'image/webp'],
},
experimental: {
optimizeCss: true,
},
};
// コンポーネント
import Image from 'next/image';
export default function Hero() {
return (
<Image
src="/hero.jpg"
alt="Hero"
width={1200}
height={600}
priority // LCP画像
placeholder="blur"
/>
);
}
React
// コード分割
const HeavyComponent = React.lazy(() => import('./HeavyComponent'));
// Suspense
<Suspense fallback={<Skeleton />}>
<HeavyComponent />
</Suspense>
バニラJavaScript
<!-- スクリプト読み込み -->
<script src="critical.js"></script>
<script src="app.js" defer></script>
<script src="analytics.js" async></script>
<!-- 画像の遅延読み込み -->
<img src="below-fold.jpg" loading="lazy" alt="Below fold">
改善優先順位
影響度順
| 順位 | 最適化項目 | 効果 |
|---|---|---|
| 1 | LCP画像最適化 | LCP ↓ |
| 2 | レンダリングブロッキングJS除去 | LCP, INP ↓ |
| 3 | 画像/埋め込みサイズ指定 | CLS ↓ |
| 4 | CDN使用 | LCP ↓ |
| 5 | ウェブフォント最適化 | CLS ↓ |
| 6 | JSバンドル分割 | INP ↓ |
クイックウィン
<!-- 1. LCP画像プリロード -->
<link rel="preload" href="hero.webp" as="image">
<!-- 2. 画像サイズ指定 -->
<img width="800" height="600" ...>
<!-- 3. JS defer -->
<script src="app.js" defer></script>
FAQ
Q1: Core Web Vitalsはランキングにどの程度影響しますか?
A: 直接的なランキング要因ですが、コンテンツ品質より重要ではありません。競合ページとコンテンツ品質が同程度の場合に決定的な役割を果たします。
Q2: モバイルとデスクトップでスコアが異なる理由は?
A: Googleは主にモバイルデータを使用します。モバイル最適化を優先してください。
Q3: 「データなし」と表示される理由は?
A: Chrome UX Reportに十分なトラフィックデータがありません。サイトのトラフィックが少ないか、新規サイトの可能性があります。
Q4: どの指標を先に改善すべきですか?
A: 一般的に:
- LCP - 最も目立つ改善
- CLS - ユーザーの不満を軽減
- INP - インタラクションの多いサイトで重要
Q5: サードパーティスクリプトが問題の場合は?
A:
- 不要なスクリプトを削除
asyncまたはdefer属性を使用- Partytownなどの Web Workerライブラリを使用
チェックリスト
LCP最適化
- LCP画像のプリロード
- 画像最適化(WebP/AVIF)
- レンダリングブロッキングリソースの除去
- TTFB < 200ms
- CDN使用
INP最適化
- 重いJSチャンクの分割
- デバウンス/スロットルの適用
- 不要なJSの削除
- サードパーティスクリプトの整理
CLS最適化
- 画像/動画サイズの指定
- 広告スペースの予約
- font-displayの設定
- 動的コンテンツのスペース予約
まとめ
Core Web Vitalsの要点:
- LCP ≤ 2.5秒: 最大コンテンツを素早く表示
- INP ≤ 200ms: インタラクションに即座に反応
- CLS ≤ 0.1: レイアウトシフトなし
モバイル最適化が鍵です。
関連ツール
| ツール | 用途 |
|---|---|
| PageSpeed分析 | Core Web Vitals測定 |
| 画像最適化 | WebP変換 |
| メタタグジェネレーター | SEOメタタグ |
著者について
Toolypet Team
Development Team
The Toolypet Team creates free, privacy-focused web tools for developers and designers. All tools run entirely in your browser with no data sent to servers.