frontend-fullchain-optimization について
frontend-fullchain-optimizationは、Web Vitalsに基づくフロントエンド性能の診断・最適化ガイドです。ページ読み込み、操作応答性、視覚安定性を調べる開発者向けに、指標の基準値、診断手順、ネットワークや描画、リソースの改善策を示します。
主な機能
- 01Web Vitalsの基準値を参照
- 02診断手順で問題箇所を特定
- 03TTFB・FCP・LCP・INPの最適化
- 04レイアウトシフトを抑えてCLSを改善
- 05ネットワーク・キャッシュ・リソースの改善策
活用シーン
- 01ページ読み込みが遅い原因の調査
- 02操作遅延やメインスレッドの長いタスクの分析
- 03画像や動的コンテンツによるレイアウトシフトの低減
- 04モバイル回線向けリソース読み込みの最適化
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ mindfold-ai/ marketplace --skill frontend-fullchain-optimizationインストール後、Claude Code で/frontend-fullchain-optimizationを入力して読み込まれたか確認します。
詳細
フロントエンドのフルチェーンパフォーマンス最適化ガイド
Web Vitals のコア指標に基づく、フロントエンドのパフォーマンス診断・最適化システムです。基本原則は、ユーザー中心 — 最適化とは、何かを増やすことではなく、減らすことです。
指標のしきい値クイックリファレンス
| 指標 | 良好 | 改善が必要 | 不良 | 単位 | 焦点 |
|---|---|---|---|---|---|
| LCP | ≤ 2.5s | 2.5s - 4s | > 4s | 時間 | 最大コンテンツの描画 |
| FCP | ≤ 1.8s | 1.8s - 3s | > 3s | 時間 | 初回コンテンツ描画 |
| INP | ≤ 200ms | 200ms - 500ms | > 500ms | 時間 | 次の描画までのインタラクション |
| CLS | ≤ 0.1 | 0.1 - 0.25 | > 0.25 | スコア | 視覚的な安定性 |
| TTFB | ≤ 800ms | 800ms - 1.8s | > 1.8s | 時間 | 最初のバイトまでの時間 |
| FID | ≤ 100ms | 100ms - 300ms | > 300ms | 時間 | 初回入力遅延 |
| TBT | 50ms を超えるタスクは長時間タスクです | — | — | 時間 | 合計ブロック時間 |
測定に関するアドバイス:P75 のみに頼らないでください。P60/P75/P90/P99 のパーセンタイルと、日次の平均/最大/最小の推移を組み合わせます。デスクトップ:P98 以上を目標にします。モバイルの主要ページ:P95〜P99 を目標にします。
診断の判断ツリー
Page loads slowly?
├── TTFB > 800ms → Network/server issue → See "TTFB Optimization"
├── FCP > 1.8s → Resource blocking/large files → See "FCP Optimization"
├── LCP > 2.5s
│ ├── TTFB & FCP normal → Slow viewport resource loading → See "LCP Optimization"
│ └── TTFB or FCP abnormal → Fix upstream metrics first
├── INP > 200ms → Long tasks blocking main thread → See "INP Optimization"
├── CLS > 0.1 → Layout shifts → See "CLS Optimization"
└── Lighthouse Performance Score
├── > 80: Few issues
├── 60-80: Needs focused analysis, priority: FCP → LCP → CLS
└── < 60: Severe issues, full audit required
INP の最適化(インタラクションの応答性)
診断:Chrome の Performance パネルで、長時間タスク(> 50ms、赤色で強調表示)を探します。フレームチャートでイベントハンドラーの実行時間を確認します。
戦略 — 長時間タスクを短いタスクに分割する:
| 方法 | 仕組み | 用途 |
|---|---|---|
setTimeout(fn, 0) | キューの末尾に新しいマクロタスクを作成します | 緊急性の低いネットワークリクエスト、DB 操作 |
Promise.resolve().then(fn) | マイクロタスクを作成し、現在のマクロタスクの直後に実行します | より速い実行が必要な副次タスク |
requestAnimationFrame(fn) | 次の再描画の前に実行します | レンダリング関連のタスク |
requestIdleCallback(fn) | 優先度が最も低く、メインスレッドがアイドル状態のときに実行します | 分析、ログ記録 |
scheduler.postTask(fn, {priority}) | 優先度を細かく制御します | 正確なスケジューリングが必要なシナリオ |
postTask の優先度:user-blocking(高)> user-visible(中)> background(低)
レイアウトとレンダリングの最適化:
calc()の使用頻度を減らし、不要な疑似クラスセレクター(nth-child、nth-last-child、not())を避けます- 要素の位置やサイズを JavaScript で頻繁に変更しないでください。まとめて更新するには
classNameまたはcssTextを使用します - ループ内で DOM の読み取りと書き込みを交互に行わないでください(レイアウトスラッシング)。まず読み取り結果を変数にキャッシュし、その後まとめて書き込みます
- 遅延読み込みされるコンテンツにはスケルトンスクリーンを使用します
- 意味のない
<div>ラッパーの代わりに<></>(Fragment)を使用します - DOM ノード数が 800 を超える場合は注意し、1400 を超える場合は過剰です
- 長いリストには仮想化を使用します(react-window/vue-virtual-scroll-list)
- Swiper のリストでは、現在の項目の前後 1 項目のみを先読みします
CSS の最適化:
tableレイアウトを避け、深くネストされた CSS セレクターを減らします- GPU アクセラレーションを利用したアニメーションを使用します。
transform/opacityはコンポジットレイヤーを生成します。リフローを引き起こすtop/leftは避けます - セマンティックな HTML 要素を使用し、意味のないタグは避けます(ボタンには
<div>ではなく<button>を使用します)
TTFB の最適化(ネットワークとサーバー)
診断式:TTFB ≈ HTTP request time + Server processing time + HTTP response time
診断方法:DevTools の Network パネルでリクエストをクリックし、Timing → 「Waiting for server response」を確認します。これが TTFB です。
ページタイプごとの TTFB の違い:静的ページ(CDN から直接配信され、最速) < SPA(HTML シェルが小さく、ほぼ静的) < SSR(Node.js での処理が必要で、最も遅い)。ページタイプに応じて基準値を調整してください。
| 方針 | 戦略 |
|---|---|
| 全般 | CDN による高速化(90% 以上のケースを解決します。デプロイ後は事前に CDN キャッシュをパージしてください)、HTTP/2 の多重化、Gzip 圧縮、コード分割と動的インポート |
| UX | 重いリクエストには Web Workers を使用し、DNS プリフェッチ <link rel="dns-prefetch"> とプリコネクト <link rel="preconnect"> を設定します |
| サーバー(SSR) | API には内部ネットワークを使用し、低頻度のデータには Redis キャッシュを使用し、リダイレクトを減らし、ビルド時に静的ページを事前生成します |
| リソースキャッシュ | アプリのホットアップデート:HTML/JS/CSS をローカルに事前ダウンロードします(TTFB ≈ 0)。PWA Service Worker のオフラインキャッシュ |
FCP の最適化(白画面と最初のコンテンツ)
診断式:FCP ≈ TTFB + Resource download time + DOM parse time + Render time
白画面の時間 ≈ FCP の時間。目標:瞬時に開くこと(< 1s)。
| 戦略 | 詳細 |
|---|---|
| レンダリングをブロックするリソースを削除 | script タグに defer または async を追加します。クリティカルでない JS は NPM バンドルまたはフレームワークのコンポーネント(例:next/script)にします |
| JS/CSS のサイズを削減 | 未使用コードを削除し、Tree Shaking とコード分割を行います |
| ネットワークペイロードを制御 | ファーストビューの画像を圧縮し、WebP/AVIF を使用します。動画はプレースホルダーを表示して遅延読み込みします |
| キャッシュ戦略 | Cache-Control: max-age=31536000(静的アセットを 1 年間キャッシュ)。JS/CSS は必要に応じて設定します |
| クリティカルリクエストの階層を浅くする | ネストしたリソース依存関係(例:CSS @import の連鎖)を減らし、クリティカルなリソースリクエストの連鎖を平坦化します |
| フォントの最適化 | 以下の「フォント最適化戦略」を参照してください |
| 白画面への対策 | PWA(海外市場)、アプリのホットアップデートによるローカル読み込み(国内市場) |
フォント最適化戦略
| 方法 | 説明 |
|---|---|
| フォント数を制限 | カスタムフォント 1 種類とシステムフォントのフォールバックのみを使用します。本文と p で異なる Web フォントを使用しないでください |
| WOFF2 を優先 | WOFF より圧縮率が 30% 高く、すべてのモダンブラウザーでサポートされています |
unicode-range によるサブセット化 | 文字範囲(例:CJK U+4E00-9FA5)を定義します。ブラウザーは必要なサブセットのみをダウンロードします |
local() によるローカルフォント | フォントをバンドルしたアプリでは、src: local('Font Name'), url(...) を使います。最初にローカルフォントを読み込むため、ネットワークリクエストは発生しません |
font-display 戦略 | swap:最初にシステムフォントを表示してから置き換えます(CLS が最小)。optional:プリロードと併用します(失敗しても再レイアウトしません)。block:読み込みを待ちます(レンダリングをブロックします)。fallback/auto:折衷案です |
| CSS Font Loading API | new FontFace() + font.load() + document.fonts.ready.then() — フォントのダウンロードタイミングと切り替えロジックをプログラムから制御します |
| 低速ネットワーク時のフォールバック | navigator.connection を使って検出します。低速なユーザーにはシステムのデフォルトフォントを表示します |
LCP の最適化(Largest Contentful Paint)
診断方法:Performance パネルで LCP マーカーの要素を確認します。Lighthouse レポートの「Largest Contentful Paint element」の項目も確認してください。
LCP のマーカーとなる 4 種類の要素:
<img>要素(最も一般的)と SVG 内の<image><video>のposter属性の画像、または最初のフレーム- CSS の
url()背景画像を持つ要素 - テキストノードを含むブロックレベル要素
主なポイント:
- LCP の時間は常に FCP の時間以上です
- TTFB と FCP が正常なのに LCP が異常な場合は、ビューポート内のリソース読み込みに問題があります
- SPA では LCP より FCP が重要です。SSR/MPA では FCP より LCP が重要です
| 戦略 | 詳細 |
|---|---|
| LCP 画像をプリロードする | <link rel="preload" href="..." as="image"> |
| フレームワークの画像コンポーネント | next/image を使用します(優先読み込みとフォーマットの最適化を含みます)。priority={true} を設定します |
| 大きな画像を分割する | 大きな背景画像を小さな画像に分割します |
| 画像フォーマット | PNG/JPEG → WebP/AVIF に変換すると、サイズを 30% 以上削減できます |
| クラウド画像パラメーター | デバイスごとに画像サイズ、品質、フォーマットを動的に設定します(例:Alibaba Cloud OSS のパラメーター) |
| リッチテキスト内の画像 | コンテンツから画像 URL を抽出し、あらかじめ <link rel="preload"> を設定します |
| 重複するプリロードを避ける | priority を指定したフレームワークの画像コンポーネント(例:next/image)を使用する場合、手動で <link rel="preload"> も追加しないでください。重複すると帯域幅を無駄に消費します |
サンプリングの推奨事項:PV が 1M 未満の場合は LCP をすべて収集し、それ以上の場合は割合サンプリングまたはしきい値ベースのレポートを使用します。
CLS の最適化(レイアウトシフト)
診断式:Layout shift score = Impact fraction × Distance fraction、CLS = SUM(all shift scores)
主な結論:要素の移動距離が大きく、影響を受けるビューポート領域が広いほど、CLS は高くなります。
| シナリオ | 最適化戦略 |
|---|---|
| 画像 | すべての <img> に width/height を設定します。モバイルでは aspect-ratio を使用し、レスポンシブ画像には srcset/<picture> を使用します |
| 動的コンテンツ | 広告や iframe 用に固定サイズのプレースホルダーコンテナーを確保します。操作なしでビューポートの上部にコンテンツを挿入するのは避けてください。下部付近への挿入は CLS への影響が小さくなります |
| CSS アニメーション | top/left/width/height の代わりに transform を使用します。寸法を変更する代わりに transform: scale() を使用します |
| フォント | font-display: optional とプリロードを組み合わせます。または、CLS への影響を軽減するため font-display: swap を使用します |
一般的な最適化のヒント
| ヒント | 説明 |
|---|---|
| ネットワーク状況の把握 | navigator.connection.effectiveType で 2G/3G/4G を検出し、通信速度の遅いユーザー向けに劣化させます(画像を小さくする、システムフォントを使う、読み込みを減らす) |
| SVG アイコン | 小さなアイコン(< 5KB / < 50px)にはすべて画像ではなく SVG を使用し、非同期リクエストを減らします |
| レスポンシブな劣化 | CSS メディアクエリーで画面サイズごとに CSS を分割し、小さな画面では背景画像の読み込みを省略します |
| キャッシュ優先 | リストデータを LocalStorage にキャッシュし、まずキャッシュを表示してから非同期で更新することで、白画面を減らします |
| リクエストの統合 | リソースを統合し、HTTP リクエスト数とドメイン数を減らします |
| レンダリング方式 | シナリオに応じて SSR(初回描画が高速)/CSR(インタラクティブ性が高い)/SSG(静的コンテンツ)を選択します |
外部サービスを使った実践例
以下の例では、CDN、OSS、Redis などの外部サービスを使って戦略を実装する方法を紹介します。
例 1:Alibaba Cloud OSS — ネットワーク状況に応じた画像品質の調整
用途:通信速度の遅いユーザーには表示内容を優先し、画像サイズとダウンロード時間を削減します。
const BASE_IMAGE_URL =
"https://oss-console-img-demo-cn-hangzhou.oss-cn-hangzhou.aliyuncs.com/example.jpg";
function getNetworkLevel() {
const connection = navigator.connection || {};
const type = connection.effectiveType || "4g";
// Slow network: slow-2g / 2g / 3g
if (/slow-2g|2g|3g/.test(type)) return "slow";
return "fast";
}
function buildOssImageUrl(baseUrl) {
const level = getNetworkLevel();
// OSS image processing params: lower resolution + quality for slow networks
const ossParams =
level === "slow"
? "x-oss-process=image/resize,w_100/quality,q_60/format,webp"
: "x-oss-process=image/resize,w_300/quality,q_82/format,webp";
return `${baseUrl}?${ossParams}`;
}
function updateHeroImage(imgEl) {
imgEl.src = buildOssImageUrl(BASE_IMAGE_URL);
}
const heroImage = document.querySelector("#hero-image");
if (heroImage) {
updateHeroImage(heroImage);
// Update resource strategy on network change
navigator.connection?.addEventListener("change", () => updateHeroImage(heroImage));
}
例 2:CDN の事前パージ(デプロイ後)
用途:SPA のデプロイ後に CDN が古いリソースを配信するのを防ぎ、バージョンの不整合を回避します。
# Executed by CI/CD or server-side — never expose keys in frontend
# Example: proactively purge entry HTML and critical static assets after deploy
curl -X POST "https://your-cdn-provider.example.com/purge" \
-H "Authorization: Bearer $CDN_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"urls": [
"https://example.com/index.html",
"https://example.com/assets/app.abc123.js",
"https://example.com/assets/app.abc123.css"
]
}'
例 3:SSR + Redis キャッシュによる TTFB の削減
用途:アクセス頻度の低い設定やファーストビューのデータを読み込む SSR ページで、リクエストごとの DB/リモート API のレイテンシーを削減します。
// Node.js (SSR) example
import Redis from "ioredis";
const redis = new Redis(process.env.REDIS_URL);
export async function getHomepageData() {
const cacheKey = "homepage:data:v1";
const cached = await redis.get(cacheKey);
if (cached) return JSON.parse(cached);
// Assume this is a slow API or DB query
const data = await fetch("https://api.example.com/homepage").then((r) => r.json());
// Cache for 60s to reduce backend pressure under high concurrency
await redis.set(cacheKey, JSON.stringify(data), "EX", 60);
return data;
}
ツールの使用に関する推奨事項
| ツールモード | 使用例 |
|---|---|
| Lighthouse ナビゲーションモード | 単一ページについて、リクエストから読み込み完了までの全プロセスを分析します |
| Lighthouse タイムスパンモード | SPA のルート遷移やフォーム操作における INP/CLS を分析します |
| Lighthouse スナップショットモード | キャンペーン、アニメーション、状態が変化するページを分析します |
| パフォーマンスパネル | 長時間タスクのフレームチャート、リソース読み込み順のタイムライン、フレームごとのレイアウトシフト分析 |
| ネットワークパネル | リクエスト数/合計サイズ/TTFB/キュー時間を確認し、CDN/プリフェッチ/HTTP2 が必要か判断します |
主な分析手順:
- FCP の表示が遅い → JS/CSS の読み込み時間を確認します。SSR の場合はサーバー API のレイテンシを確認します
- FP と FCP の間隔が長い → レンダリングを妨げている長時間タスクを確認します
- FCP と LCP の間隔が大きい → ビューポート内のリソースが多すぎる、または大きすぎます。SSR が十分に活用されていない可能性があります
- CLS が複数回急上昇する → 合計が 0.25 を超える場合は、優先して修正する必要があります
手動測定の要件
- デフォルトでは、Lighthouse と Performance の測定結果を手動で収集したデータとして扱います
- 同じページ/ルートを 2~3 回測定し、中央値を使用することを推奨します
- デバイスの種類、ブラウザーのバージョン、ネットワークの状態、ページが SPA/SSR/SSG のいずれであるかを記録します
- 可能であれば、変更前後の比較で測定環境を一定に保ちます
手動でのデータ収集手順
- Chrome DevTools を開きます
- 対象のページまたはルートで Lighthouse を手動で実行します
- 主な指標(LCP/FCP/INP/CLS/TTFB)を記録します
- Performance パネルを開き、同じシナリオのトレースを手動で記録します
- Network パネルを使用して、TTFB、リクエストのウォーターフォール、負荷の大きいリソースを確認します
- 変更前後の比較に使用できるよう、スクリーンショットまたはエクスポートしたトレースを保存します
手動測定がない場合
ユーザーがLighthouse または Performance による手動測定をまだ行っていない場合、根本原因を確実なものとして断定しないでください。
代わりに、次のようにします。
- 手動測定を行わずに推定した診断であることを明示します
- 表面上の症状、コード構造、ページの種類に基づく仮説に基づいた提案を提示します
- 各提案に、改善が最も見込まれる指標を明記します
- 変更後に Lighthouse と Performance で手動測定することを推奨します
手動データがない場合に推奨される代替アドバイス
- ページに白い画面が長時間表示される場合 →
FCPの改善案を優先します - ヒーロー画像または最初の画面のコンテンツが遅れて表示される場合 →
LCPの改善案を優先します - クリックや入力の反応が遅く感じられる場合 →
INP/TBTの改善案を優先します - 読み込み中にページが動く場合 →
CLSの改善案を優先します - コンテンツが表示される前からページ全体の表示開始が遅い場合 →
TTFBの改善案を優先します
これらの推奨事項は、最善を尽くした仮説であり、検証済みの結論ではありません。
単独での使用モード
この Skill には、実行可能な判断基準、最適化戦略、コード例、外部サービスの実装パターンが含まれています。コース資料にアクセスする必要なく、単独で使用できます。
標準的な実行手順
- 現在の状態を収集する
- 主な指標(LCP/FCP/INP/CLS/TTFB)を取得します(少なくとも P75 と日次平均)
- Lighthouse、Performance、Network による手動測定から根拠を収集します
- 優先順位を決める
- まず最も悪い指標(Poor)を修正し、次に Needs Improvement を修正します
- 推奨順序:
FCP → LCP → CLS → INP → TTFB(ビジネスニーズに応じて調整します)
- 戦略を選ぶ
- この Skill の診断用ディシジョンツリーに従い、対応する最適化の分岐を選択します
- 外部サービスについては、上記の「実践例」セクションを優先します
- 実装して検証する
- 小さな単位で段階的にコミットし、変更ごとに最適化の種類を 1 つにします
- 可能であれば、中央値を使って 2~3 回再テストし、実際に改善したことを確認します
- 記録して再発を防ぐ
- 変更前後の指標を記録します
- 主要なチェック項目を CI に追加することを検討します(Lighthouse/パフォーマンス予算)
提出テンプレート
## Optimization Target
- Page/Feature:
- Target Metric:
- Current Value:
- Target Value:
## Evidence
- Manual Lighthouse evidence:
- Manual Performance evidence:
- Network evidence:
## Execution Strategy
- Approach:
- External services involved:
- Risk & rollback:
## Result Verification
- Before:
- After:
- Conclusion:
使用上の制約
- 体感速度を優先して、コア機能の正確性を犠牲にしないでください
- 1 人のユーザーに発生した異常を、全体的なパフォーマンスの問題として扱わないでください
- 検証せずに最適化の成功を主張しないでください
- Lighthouse または Performance による手動測定がない場合は、アドバイスが推測に基づくものであることを明確にし、追加の検証を推奨してください