第198章:練習:アイキャッチ画像を最適化する🖼️
この章は「ブログ記事の先頭にあるアイキャッチ(ヒーロー画像)」を、速く・崩れず・キレイにする練習だよ〜😊✨
完成したら、ページの体感速度がグッと上がることが多い!🚀
🎯 この章のゴール(できたら勝ち!)🏁
- アイキャッチを
next/imageで表示できる📸 - **レイアウトがガクッと動かない(CLS対策)**ができる🧱
- スマホ/PCで無駄にデカい画像を取らないように
sizesを付けられる📱💻 - アイキャッチがページの主役なら
priorityで先読みできる⚡
Next.js の
<Image>は、適切なサイズ配信・モダン形式(WebPなど)・レイアウト安定などを助けてくれるよ〜💡
(公式ドキュメント)oaicite:0
🧠 まずは全体像(画像が速くなる流れ)✨

✅ ステップ0:アイキャッチ画像の「正解の形」を作る🧁
アイキャッチはだいたい「横長」が多いよね📷✨
おすすめはこのへん👇(迷ったらコレでOK!)
- 📐 比率:16:9(例:1600×900)か 1200×630(OGPっぽい比率)
- 📦 ファイルサイズ目標:まずは 200KB前後を目標に(写真なら特に!)
- 🧼 やりすぎ注意:極端に圧縮すると文字や輪郭がモヤる😵💫
Next.js 側でも最適化はしてくれるけど、元が8MBとかだと「加工コスト」も上がりがちなので、元画像も軽くしておくと安定だよ🙆♀️
✅ ステップ1:画像の置き場所を決める(おすすめは2択)🗂️
A案:静的import(いちばん楽&きれい✨)
placeholder="blur"が使いやすい(自動でぼかしプレースホルダが入りやすい)🫧width/heightも自動で取れることが多い📏
静的importだと
width/heightやblurDataURLが自動で入る例が公式にあるよoaicite:1
B案:public/ 配下(単純で分かりやすい)
src="/images/cover.jpg"みたいに書ける🧁- ただし
placeholder="blur"は自分で用意する必要が出やすい(なくてもOK!)
今回は練習なので、**A案(静的import)**でいくね😊✨
✅ ステップ2:アイキャッチ用コンポーネントを作る🧩🖼️
📁 例のフォルダ構成
app/components/Eyecatch.tsxapp/assets/eyecatch.jpg(ここに置く想定)
1) app/components/Eyecatch.tsx を作成✍️
import Image, { type StaticImageData } from "next/image";
type Props = {
src: StaticImageData;
alt: string;
priority?: boolean;
};
export function Eyecatch({ src, alt, priority = false }: Props) {
return (
<figure
style={{
position: "relative",
width: "100%",
aspectRatio: "16 / 9",
overflow: "hidden",
borderRadius: 16,
margin: 0,
}}
>
<Image
src={src}
alt={alt}
fill
placeholder="blur"
priority={priority}
sizes="(max-width: 768px) 100vw, 900px"
style={{ objectFit: "cover" }}
/>
</figure>
);
}
ここが超大事ポイントだよ〜!🔑✨
fill:親要素いっぱいに広げる🧃(親がposition: relative必須)(Next.js)aspectRatio: "16 / 9":高さが確保される → 画像読み込みでガクッと動きにくい🧱sizes:これがあると端末に合わせて適切なサイズを取りやすい📱💻(無いと 100vw 想定でデカめを取りがち)(Next.js)priority:アイキャッチが LCP主役ならtrueにする⚡(使いすぎ注意!)(Next.js)
✅ ステップ3:記事ページで使う📰✨
例として app/posts/sample/page.tsx みたいなページで使うね!
import cover from "@/app/assets/eyecatch.jpg";
import { Eyecatch } from "@/app/components/Eyecatch";
export default function Page() {
return (
<main style={{ maxWidth: 900, margin: "24px auto", padding: "0 16px" }}>
<Eyecatch src={cover} alt="サンプル記事のアイキャッチ" priority />
<h1 style={{ marginTop: 20 }}>サンプル記事🌸</h1>
<p>ここに本文が入るよ〜😊</p>
</main>
);
}
✅ ステップ4:最適化できてるか確認する👀🔍(かんたん)
開発サーバー起動👇
npm run dev
そしてブラウザでページを開いて…
🔎 かんたんチェック3点セット
- 🧱 スクロールしてもレイアウトが跳ねない?(CLSっぽい動きがない)
- 📱 スマホ幅にした時、画像が必要以上に重くない?
- 🧰 DevTools → Network で画像を見ると、
/_next/image?...みたいな最適化配信っぽい挙動が見えることが多いよ(環境による)✨
🔥 追加ミッション(ちょい発展)🎮✨
ミッションA:sizes を自分のレイアウトに合わせて調整💅
今はこうしてる👇
- スマホ:
100vw(画面幅いっぱい) - PC:
900pxまで
もしPCで「左右に余白がもっと広い」なら、900px を 720px にしてみてね😊
小さくできるほど軽くなることが多いよ⚡
sizesはfillやレスポンシブCSSのとき特に重要だよ(Next.js)
ミッションB:外部URL画像を使う場合の設定(やる人だけ)🌍🧩
もし src="https://...." を使うなら、許可リストが必要だよ〜🛡️
next.config.ts に remotePatterns を追加する感じ!
import type { NextConfig } from "next";
const config: NextConfig = {
images: {
remotePatterns: [
{
protocol: "https",
hostname: "example.com",
port: "",
pathname: "/images/**",
search: "",
},
],
},
};
export default config;
公式の案内:リモート画像は
remotePatternsを設定して安全に使う(Next.js)
🧯 よくある失敗あるある(先に潰す!)💣
- ❌
fillなのに親要素がposition: relativeじゃない → 画像が変な場所に出る - ❌
sizesを付けない → スマホでも大きい画像を取りがちで重くなる(Next.js) - ❌
priorityをあちこちに付ける → 先読みが増えて逆に混むことがある😵💫 - ❌ そもそも元画像がデカすぎ(数MB)→ まずリサイズ&圧縮しよ🧼
✅ この章のクリア条件🎉
- アイキャッチが
next/imageで表示できた🖼️✨ - 画像読み込みでレイアウトがガクッと動きにくい🧱
sizesを付けて「スマホは軽く、PCはキレイ」を狙えた📱💻⚡- 主役画像だけ
priorityにできた(必要なときだけ!)⚡
ここまでできたら第198章クリアだよ〜!🙌🌸
::contentReference[oaicite:8]{index=8}