エッジ時代の画像配信最適化 CDN 設計 2025
公開: 2025年9月22日 · 読了目安: 2 分 · 著者: Unified Image Tools 編集部
検索流入を伸ばすうえで「速い画像配信」は避けて通れません。本稿では、ユースケース別に CDN/エッジの設計ポイントを整理し、実運用でハマりがちな罠を回避するためのチェックリストを提供します。
画像CDNの基本設計
- 変換単位の明確化(元画像/変換後)
- キャッシュキーの定義(URL,
Accept
,Accept-Encoding
, DPR 等) - 期限と無効化戦略(Fingerprint,
Cache-Control
,stale-while-revalidate
) - レスポンシブ画像との協調(
srcset
/sizes
の正確性)
内部リンク: srcset 設計の基本, INP重視の配信, 画像配信最適化 2025 — Priority Hints / Preload / HTTP/2 の実戦ガイド
HTTP ヘッダー実践
Cache-Control: public, max-age=86400, stale-while-revalidate=259200
Vary: Accept, DPR
Accept-Ranges: bytes
Timing-Allow-Origin: *
Vary: Accept
で AVIF/WebP/JPEG を適切に切り替えVary: DPR
を導入する場合は、サーバ側でDPR別の生成/キャッシュを分離- SSG/ISR では URL 指紋(例:
hero-640.avif?v=20250922
)が最も安全
Priority Hints / Early Hints
<!-- LCP候補に対し -->
<link rel="preload" as="image" href="/images/hero-1200.avif" imagesrcset="..." imagesizes="(min-width: 1024px) 1200px, 90vw" fetchpriority="high" />
fetchpriority="high"
は「なんでも高優先度」にしない(CLS対策と競合)- 可能なら 103 Early Hints で
preconnect
とpreload
を先出し
エッジ変換とオリジン変換の住み分け
- エッジ: 切替頻度が高い派生(AVIF/WebP、幅/品質差分)
- オリジン: 高コストかつ再現性が必要な処理(メタデータ編集、ICC保持、透過合成)
関連ツール: フォーマット変換, 一括圧縮, プレースホルダー生成
典型的な落とし穴
Vary
を付けたのに CDN がキーに入れていない(設定の二重化に注意)Accept: image/avif
のない古いクローラへ AVIF を返してインデックス崩れ- 画像最適化サービスとアプリCDNの二重変換で品質劣化
チェックリスト(保存版)
-
[ ] LCP候補の
fetchpriority
とsizes
は現実のレイアウトと一致 -
[ ] キャッシュキーに URL 指紋 or
Vary
を導入済み -
[ ] エッジ変換のエラー時に安全なフォールバック(JPEG)
-
[ ] 画像
alt
と構造化データで 画像SEO を満たす
キャッシュキー設計のディテール
- 推奨キー:
URL + Accept + DPR + Width + Quality
- 変数化: Edge Function/Worker で
q
w
を正規化(例: 320/480/640/…) - 応答ヘッダ
Cache-Control: public, max-age=604800, stale-while-revalidate=2592000
Vary: Accept, DPR
CDN-Cache-Status: HIT
AVIF/WebP フォールバック戦略
Accept
判定で AVIF 優先、次に WebP、最後に JPEG- 失敗時のフォールバックをサーバ側で実装(タイムアウト/エラー時は JPEG)
- クライアントでは
srcset type
指定でブラウザ選択に任せる
<picture>
<source type="image/avif" srcset="hero.avif 1x, hero@2x.avif 2x" />
<source type="image/webp" srcset="hero.webp 1x, hero@2x.webp 2x" />
<img src="hero.jpg" alt="..." width="1200" height="630" />
</picture>
自動リサイズの正規化
sizes
と連動する幅セットを固定: 320/480/640/768/960/1200/1600/2000- クエリ
w
が近似値なら最近傍へ丸め、キャッシュ断片化を防止 q
は用途別にプリセット: サムネ 60/写真 70/UI 80 など
セキュリティと悪用対策
- 署名付きURLで無制限変換を防止(
w
h
q
fmt
をサイン) - レート制限と失敗時の回路遮断(Circuit Breaker)
- 画像フィルタの過剰適用を禁止(CPU DoS)
観測/コスト最適化
- ログ項目: URL, fmt, w, q, dpr, cacheStatus, genTime, size
- 可視化: フォーマット別ヒット率とサイズ中央値、p95 生成時間
- コスト抑制: 人気サイズを前取り生成、長期 TTL で元画像への負荷軽減
エッジ関数(擬似コード)
export default async function handle(req) {
const u = new URL(req.url)
const w = normalizeWidth(u.searchParams.get('w'))
const q = normalizeQuality(u.searchParams.get('q'))
const fmt = negotiate(req.headers.get('Accept'))
const key = `${u.pathname}?w=${w}&q=${q}&fmt=${fmt}`
const cached = await caches.default.match(key)
if (cached) return cached
const out = await transform(u.pathname, { w, q, fmt })
return new Response(out.body, { headers: responseHeaders({ fmt, w, q }) })
}
トラブルシューティング
- 古いブラウザで画像が出ない →
Accept
判定ミス、type
付き<source>
で対応 - 生成が遅い → 幅セットの削減、品質のプリセット化、再圧縮回避
- 画質ムラ →
q
を用途別に固定、AVIF はeffort
を中庸に
FAQ
Q. WebP/AVIF を常に最優先すべき?
A. 互換と生成コストのバランスが重要です。ブランド品質重視なら要所で JPEG も有効。
Q. Vary
を増やすとキャッシュヒットが下がりませんか?
A. 幅/品質を正規化すれば断片化は抑制できます。DPR は限定的に導入を。
まとめ
CDNの“正しいキー設計”と“LCP候補の限定的最適化”が、体感速度と検索流入を同時に伸ばす最短ルートです。まずはヒーロー画像だけを対象に、小さく A/B テストから始めましょう。