Next.js: next/image の fill には sizes も付ける
fill を使った <Image> に sizes が無いと、ブラウザは画像が画面幅いっぱい(100vw)だと見なし、カードの小さな枠でも大きな画像をダウンロードする。
なぜ必要か
next/image は複数の幅の画像を srcset で用意し、ブラウザは sizes を見て「実際に表示される幅」に合う 1 枚を選ぶ。width / height を固定しない fill では Next.js が表示幅を知らないので、sizes が無いと既定の 100vw が使われる。3 列のカード一覧でも、画面幅ぶんの画像を取ってしまう。
やり方
tsx
<div style={{ position: 'relative', aspectRatio: '16 / 9' }}>
<Image
src={post.cover}
alt=""
fill
sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
style={{ objectFit: 'cover' }}
/>
</div>- レイアウトの実際の幅に合わせて書く(1 列なら
100vw、2 列なら50vwなど)。 fillの親要素にはposition: relative(またはabsolute/fixed)と大きさが必要。
確かめ方
- DevTools の Network で、読み込まれた画像の
w=パラメータ(/_next/image?url=...&w=3840など)が表示幅に見合っているか見る。 - Lighthouse の「適切なサイズの画像」の指摘も目安になる。
注意点
sizesを付けると、Next.js は小さい幅の候補もsrcsetに含めるようになる。付けないfillでは大きい候補ばかりになる。- AI エージェントが生成したコードは
fillだけで終わっていることが多いので、レビューで確認する(元投稿の趣旨)。