Skip to content
Published on

パフォーマンス·Core Web Vitals 2025 — LCP·CLS·INP·RUM·Image·Font·JS·Cache·Edge·CDN·HTTP/3 (シーズン6 第6回)

Authors

プロローグ — パフォーマンスは機能ではない

開発者がよく誤解すること: 「パフォーマンス最適化は出荷後のチューニング」。2025年の現実は違う。

  • Google検索順位にCore Web Vitals反映 (2021~)。
  • Eコマース研究: LCP 0.1秒改善あたり転換率+1% (Amazon、Booking)。
  • 2024年INP正式採用で応答性競争。
  • 日韓ユーザーの 地下鉄5G·低電力モード 現実。

「パフォーマンスは機能ではない。全機能の条件だ」

良いAI·UX·モーションも遅ければ無価値。本稿は2025年実戦ガイド。


1章. Core Web Vitals 2025 — 3指標

LCP (Largest Contentful Paint)

  • 最大コンテンツがビューポートにレンダされた時点。
  • Good ≤ 2.5s、Needs ≤ 4s、Poor > 4s。
  • 通常Heroイメージ·テキストブロック。

CLS (Cumulative Layout Shift)

  • ビューポート移動 (レイアウトシフト) 累積。
  • Good ≤ 0.1、Needs ≤ 0.25、Poor > 0.25。
  • サイズ未指定画像·広告挿入·フォントロードが主犯。

INP (Interaction to Next Paint) — 2024 FID置換

  • 入力から次ペイントまで。
  • Good ≤ 200ms、Needs ≤ 500ms、Poor > 500ms。
  • 遅いJS·メインスレッドブロック検知。ページ全ライフタイム評価。

測定基準

  • p75 百分位 — 大半のユーザー体験。
  • 実ユーザー、28日rolling (CrUX)。
  • Mobile·Desktop分離

補助指標

  • FCP 1.8s目標、TTFB 0.8s目標。TTIは旧式 — INPが置換。

2章. RUM vs Synthetic

Synthetic

  • 制御環境 (Lighthouse、WebPageTest、SpeedCurve)。
  • 利: 再現性、回帰検知。欠: 実ユーザーと乖離。

RUM

  • 実ブラウザ (Vercel Speed Insights、Datadog RUM、New Relic、Sentry、CrUX)。
  • 利: 真実。欠: ノイズ、小サンプルで外れ値が支配。

両方

  • CIにLighthouse、本番にRUM、CrUXで競合ベンチマーク

CrUX

Chromeオプトインデータ、月次集計。PageSpeed Insightsで活用、BigQueryで公開。


3章. Critical Rendering Path

Network → Parse HTML → CSSOM → Render Tree → Layout → Paint → Composite。

主要ボトルネック

  • Render-blocking CSS、Render-blocking JS、Font swap (FOIT/FOUT)。

2025年標準

  1. Critical CSSをAbove-the-foldにインライン。
  2. <script defer>/async
  3. <img fetchpriority="high"> をLCP画像に。
  4. <link rel="preconnect"> サードパーティオリジンに。
  5. <link rel="preload"> 重要フォント·Hero画像に。

4章. JSバンドルダイエット

2025年の良サイズ: 初期 < 170kb gzipped、ルート < 50kb。

バンドラ地図

  • esbuild (Go)、swc (Rust、Next.js内蔵)、Rollup (ライブラリ)、Turbopack (Next 15デフォルト)、Vite (Rollup裏)、Rspack (RustでWebpack互換)、Bun (ランタイム+バンドラ)。

よくある犯人

  • momentdate-fns or dayjs
  • lodash 全部 → 個別import。
  • react-icons → 直接SVG。
  • CommonJSパッケージがツリーシェイキングをブロック。"sideEffects": false 明示。
  • 重いウィジェット (チャート、モーダル) はDynamic import。
  • Polyfill過剰 — Baseline 2024をターゲット。
  • ランタイムCSS-in-JS → ゼロランタイム (Linaria、Vanilla Extract、Pigment) またはTailwind/CSS Modules。

5章. 画像最適化 — LCPの要

フォーマット

AVIF (最強圧縮) + WebP + JPEGフォールバック。ベクタはSVG。

Next.js <Image>

import Image from 'next/image'
<Image src="/hero.jpg" width={1200} height={600} priority placeholder="blur" blurDataURL={blur} alt="Hero" />

自動AVIF/WebP、レスポンシブsrcset、デフォルトlazy (priorityでeager)、CLS防止。

コツ

  • 常に width/height 指定。
  • Lazy + priority併用。
  • LCP画像: preload + fetchpriority="high"
  • Hero画像はインラインSVG/data-URL検討。

6章. フォント最適化

font-display

  • swap — フォールバック先 (速い、CLSリスク)。
  • optional — 100ms内でロードなければフォールバック維持 (CLSなし)。
  • fallback — 中間。

size-adjust + ascent-override

フォールバックとWebフォントのメトリクス整合 — CLS大幅減。

サブセット化

日韓中フォントはMBオーダー。常用漢字·KS X 1001 2,350字等にサブセット。SubfontやGlyphhangerで自動化。

Variable Font

1ファイルで全weight·width。日本語はNoto Sans JP、韓国語はPretendard Variable、Latin語はInter/Geist。

推奨スタック (日本語)

Noto Sans JP / Yu Gothic + font-display: swap + size-adjust


7章. Caching

HTTPキャッシュ

  • Cache-Control: public, max-age=31536000, immutable をハッシュ済み資産に。
  • no-cache で常時検証、no-store は絶対保存しない。
  • ETag/Last-Modifiedで条件付きリクエスト。
  • stale-while-revalidate で体感速度↑。

Next.js 15 Caching (再設計)

Request Memoization、Data Cache、Full Route Cache、Router Cache。2025~: 明示的 use cache ディレクティブでopt-in。

Service Worker

Offline、app-shell、アセットcache-first (Workbox)。iOS制限緩和でPWA復活気配。

Edgeキャッシュ

CDNレベル stale-while-revalidateISR は今もNext.js代表技法。


8章. Edge·CDN·HTTP/3

役割

地理的近接、オリジン負荷減、TLS/HTTP/3/圧縮オフロード。

プレイヤー

Cloudflare (価格·機能バランス最強)、Vercel Edge、Fastly (VCL)、AWS CloudFront、Netlify Edge。日本: さくら、IIJ、AWS Tokyo。

Edge Function

Cloudflare Workers、Vercel Edge、Deno Deploy、Fastly Compute@Edge。Cold Startほぼなし (V8 Isolate)。A/B、認証、Rate Limit、i18nに。

HTTP/3 (QUIC)

UDP、Head-of-line Blocking解消、0-RTT、TLS 1.3内蔵。2025年CDNデフォルト。モバイル·不安定ネットワークで特に威力。


9章. INP最適化

Long Task (>50ms) がメインスレッドを占有して応答性破壊。

  1. 検索input·スクロールリスナーにDebounce/Throttle
  2. Scheduler API: scheduler.postTask(() => heavy(), { priority: 'background' })
  3. React 18+の**useDeferredValue/useTransition**。
  4. 重い計算はWeb Workers
  5. 長リストに仮想化 (react-window、TanStack Virtual)。
  6. 偶発使用機能をコード分割

Chrome DevTools Performance → INPで測定、本番はLong Task API。


10章. ツーリング

  • Vercel Speed Insights — Vercelでゼロ設定RUM。
  • Datadog RUM / New Relic — エンタープライズ級。
  • CrUX Dashboard — 無料、オリジン単位。
  • PageSpeed Insights — Lighthouse + CrUX結合。
  • WebPageTest — 最高精度Synthetic。

11章. 実戦チェックリスト

プロジェクト初期

  • フレームワークImage、font-display: swap + size-adjust、Critical CSS。
  • Bundle Analyzer、Lighthouse CIしきい値 (LCP<2.5sCLS<0.1INP<200ms)。
  • RUM (Vercel Speed Insightsまたは自前)。

リリース前

  • LCP原因分析 (DevTools Performance insights)、INPハンドラ点検、画像サイズ、バンドルサイズ、フォントpreload、3G Fastエミュレーション。

リリース後

  • RUM p75推移、事故時ロールバック、週次Performance Review

12章. 2025年高度パターン

  • Partial Pre-Rendering (PPR) — Next.js 15、静的シェル+動的穴。
  • Islands — Astro、基本静的+JS島のみ。
  • Qwik resumability — 初期JSほぼ0。
  • Bun/Deno — SSR起動高速。
  • Turbopack — Next.js 15デフォルト。
  • Serverストリーミング — RSC + Suspense。

12項目チェックリスト

  1. CWV p75をRUMで追跡?
  2. p75で LCP<2.5sCLS<0.1INP<200ms?
  3. LCP画像に priority + fetchpriority="high"?
  4. 全画像に明示 width/height?
  5. フォント font-display + size-adjust?
  6. 初期バンドル <170kb、ルート <50kb?
  7. 重いコードにDynamic import?
  8. CDN + Edgeキャッシュ設定?
  9. HTTP/3有効?
  10. Lighthouse CIで回帰検知?
  11. 本番でRUM運用?
  12. 日韓モバイル/地下鉄ネットワークテスト?

10アンチパターン

  1. 実ユーザー計測なしで出荷。
  2. Lighthouseスコア最適化、p75 RUMを見ない。
  3. サイズ未指定画像 (CLS爆弾)。
  4. font-display: block (FOITでコンテンツ非表示)。
  5. 巨大な moment.js/lodash フル import。
  6. ホットパスのランタイムCSS-in-JS。
  7. LCP画像の <link rel="preload"> 忘れ。
  8. INPをFIDのようにテスト (単発インタラクションだけ)。
  9. RUMサンプリング低すぎ、テール回帰検知不能。
  10. 日韓ネットワーク現実を無視。

次回予告

シーズン6 第7回: 接続性と国際化 2025 — WCAG 2.2、EU Accessibility Act、ARIA、next-intl、日韓タイポグラフィ、RTL。

「速いプロダクトは良いプロダクト。遅いプロダクトは存在しないプロダクトだ」

— パフォーマンス·Core Web Vitals編、完。