imgタグとNext.jsのImageは何が違う? 画像最適化の仕組みと基本的な使い方をやさしく解説
HTMLでは、画像を表示するときに
imgタグを使います。
ところがNext.jsでは、
Imageという専用のコンポーネントが用意されています。
どちらも画像を表示する点は同じですが、
読み込み速度、画像サイズ、レイアウトの安定性などに違いがあります。
今回は、初心者が最初に知っておきたい違いと使い方を整理します。
imgタグがあるのに、なぜImageを使うの?
HTMLで画像を表示するときは、
次のようにimgタグを使います。
<img
src="/images/photo.jpg"
alt="記事の写真"
>
Next.jsでは、同じ画像を次のように書けます。
import Image from "next/image";
<Image
src="/images/photo.jpg"
alt="記事の写真"
width={800}
height={500}
/>
画像が表示できるなら、imgタグでもよいのでは?
画面上では同じ写真が表示されます。
それなのに、なぜNext.jsでは
Imageコンポーネントを使うのでしょうか。
大きな理由は、 Webサイトで使う画像を効率よく配信し、 ページを快適に表示するためです。
HTMLのimgタグとは?
imgタグは、
HTMLで画像を表示するための要素です。
Next.jsに限らず、 通常のHTMLやWordPressなどでも使えます。
基本的な書き方
<img
src="/images/cat.jpg"
alt="窓辺に座っている猫"
width="800"
height="500"
>
src
alt
width
height
imgタグはシンプルで自由度が高く、 ブラウザーが標準で理解できる画像要素です。
imgタグ自体が悪いわけではありません。 Next.jsの画像最適化が必要ない場面や、 特殊な画像表現ではimgタグを使う場合もあります。
Next.jsのImageとは?
Imageは、
Next.jsが提供するReactコンポーネントです。
HTMLのimgタグをもとにしながら、 画像のサイズ調整や遅延読み込みなど、 Webページの表示を助ける仕組みが追加されています。
画面サイズに合った画像配信や、 レイアウトの安定化を支援します。
最初にimportする
import Image from "next/image";
JSX内にImageを書く
export default function Page() {
return (
<Image
src="/images/cat.jpg"
alt="窓辺に座っている猫"
width={800}
height={500}
/>
);
}
TSXでは、
数値を文字列ではなくJavaScriptの値として渡すため、
width={800}のように波括弧を使います。
width="800"
width={800}
imgタグとImageの主な違い
どちらも画像を表示しますが、 Next.jsのImageにはWebサイト向けの最適化機能があります。
next/imageから必要画像の準備やサイズ調整は、 制作者側で管理します。
端末や表示条件に合わせた 画像配信を支援します。
画像最適化とは?
Webサイトの画像は、 ページのデータ量の中でも大きな割合を占めやすい要素です。
たとえば、横幅2000pxの大きな写真を スマートフォンの小さな画面へそのまま配信すると、 必要以上に大きなデータを読み込むことになります。
Imageを使うと、 ブラウザーは用意された画像候補の中から、 表示環境に合ったサイズを選びやすくなります。
端末に対して必要以上に大きな画像を避けます。
対応環境では効率的な画像形式を利用できます。
画面外の画像を必要なタイミングで読み込みます。
画像用の領域をあらかじめ確保します。
画質を極端に落とすことではなく、 表示に必要な品質を保ちながら、 不要に大きなデータの読み込みを減らすことです。
画像読み込み時のレイアウトずれを防ぐ
ページを開いた直後、 画像の読み込みが終わってから文章やボタンが 下へ押し出されることがあります。
Imageでは、
widthとheightから画像の比率を判断し、
読み込み前から必要な領域を確保できます。
public内の画像を表示する
Next.jsでは、
publicフォルダーへ画像を置くと、
URLの先頭から画像を指定できます。
import Image from "next/image";
export default function Page() {
return (
<Image
src="/images/cat.jpg"
alt="窓辺に座っている猫"
width={800}
height={500}
/>
);
}
public/images/cat.jpg
/images/cat.jpg
srcへ
/public/images/cat.jpg
と書くのではなく、
/images/cat.jpg
と指定します。
画像をimportして表示する
プロジェクト内の画像は、 ファイルとしてimportして表示する方法もあります。
import Image from "next/image";
import catImage from "./cat.jpg";
export default function Page() {
return (
<Image
src={catImage}
alt="窓辺に座っている猫"
/>
);
}
画像を静的にimportした場合は、
Next.jsが画像ファイルの横幅と高さを取得できるため、
widthとheightを
省略できる場合があります。
src="/images/cat.jpg"
src={catImage}
microCMSなどの外部画像を表示する
microCMSから取得したアイキャッチ画像は、 Next.jsのプロジェクト内ではなく、 外部のサーバーに保存されています。
Imageへ画像URLを渡す
<Image
src={article.eyecatch.url}
alt={article.title}
width={article.eyecatch.width}
height={article.eyecatch.height}
/>
ただし、外部画像をImageで表示するには、
許可する画像URLを
next.config.tsなどへ設定します。
remotePatternsを設定する
import type { NextConfig } from "next";
const nextConfig: NextConfig = {
images: {
remotePatterns: [
{
protocol: "https",
hostname: "images.microcms-assets.io",
},
],
},
};
export default nextConfig;
protocol
通信方式
https
hostname
画像を取得するドメイン
images.microcms-assets.io
remotePatternsでは、 Next.jsのImageで読み込みを許可する外部画像の範囲を指定します。 必要なドメインだけを設定します。
fillを使って枠いっぱいに表示する
記事カードのサムネイルなどでは、 画像を決められた枠いっぱいに表示したいことがあります。
そのようなときは、
widthとheightの代わりに
fillを使えます。
<div className="thumbnail">
<Image
src={article.eyecatch.url}
alt={article.title}
fill
sizes="(max-width: 767px) 100vw, 400px"
/>
</div>
.thumbnail {
position: relative;
width: 100%;
aspect-ratio: 16 / 9;
overflow: hidden;
border-radius: 16px;
}
.thumbnail img {
object-fit: cover;
}
fillを使う場合は、
親要素にposition: relative;を設定し、
幅と高さ、またはaspect-ratioで
表示領域を作ります。
sizesは何のために使う?
sizesは、
画像が画面上でどのくらいの横幅になるかを
ブラウザーへ伝えるための指定です。
sizes="(max-width: 767px) 100vw, 400px"
画面幅いっぱい程度で表示
約400pxで表示
Imageが画面上で400px程度しか使われないのに、 ブラウザーが非常に大きな画像を選ばないようにするための 手掛かりになります。
fillを使うときはsizesも確認
レスポンシブな画像でsizesを適切に設定すると、 表示幅に合った画像候補を選びやすくなります。
object-fitで画像の見せ方を調整する
画像の縦横比と表示枠の縦横比が違う場合は、
CSSのobject-fitで見せ方を調整できます。
一部が切れても、余白を作らずに表示します。
画像全体を表示するため、余白ができる場合があります。
.thumbnail img {
object-fit: cover;
}
枠をきれいに埋めたい
画像全体を見せたい
alt属性には何を書く?
Imageでもimgタグと同じように、
alt属性が必要です。
altには、 画像が表示されない場合や、 画像を視覚的に確認できない場合でも内容が伝わるように、 画像の意味を簡潔に書きます。
alt="画像"
alt="窓辺で眠る白い猫"
記事タイトルを利用する例
<Image
src={article.eyecatch.url}
alt={`${article.title}のアイキャッチ画像`}
width={article.eyecatch.width}
height={article.eyecatch.height}
/>
情報を持たない装飾画像では、
状況に応じてalt=""とし、
読み上げの対象から外すことがあります。
ページ上部の重要な画像
通常のImageは、 画面に近づいたタイミングで読み込む遅延読み込みを利用します。
ただし、ページを開いた直後から見えるメインビジュアルなどは、 早く読み込みたい重要な画像です。
<Image
src="/images/main-visual.jpg"
alt="サービスのメインビジュアル"
width={1600}
height={900}
preload
/>
読み込みを優先する指定は、 ページ上部の主要画像などに限定します。 多くの画像を同時に優先すると、 かえって読み込みを妨げる場合があります。
Next.jsでもimgタグを使う場面はある?
Next.jsだからといって、 すべてのimgタグが禁止されるわけではありません。
Next.jsの画像最適化を利用しないほうが適切な画像や、 特殊な実装ではimgタグを選ぶ場合があります。
- 記事のアイキャッチ
- 商品写真
- メインビジュアル
- プロフィール写真
- 通常のコンテンツ画像
- 最適化しない特殊な画像
- 外部ライブラリの制約がある画像
- picture要素と細かく組み合わせる場合
- Next.jsの最適化を意図的に使わない場合
よくあるつまずき
import Image from "next/image";
src="/public/images/cat.jpg"
→
src="/images/cat.jpg"
<Image
src="/images/cat.jpg"
alt="窓辺に座っている猫"
width={800}
height={500}
/>
microCMSなどの外部画像は、 next.config.tsのremotePatternsを確認します。
.thumbnail {
position: relative;
width: 100%;
aspect-ratio: 16 / 9;
}
<Image
src={article.eyecatch.url}
alt={article.title}
fill
sizes="(max-width: 767px) 100vw, 400px"
/>
親要素の縦横比と画像の縦横比を確認し、
object-fit: cover;や
containを設定します。
情報を伝える画像では、 画像ごとの内容が分かる代替テキストを設定します。
まとめ:通常の画像表示ではImageから考える
HTMLのimgタグとNext.jsのImageは、 どちらもWebページへ画像を表示するために使います。
Imageはimgタグの働きをもとに、 Next.jsの画像最適化機能を利用できるようにした Reactコンポーネントです。
今回覚えておきたいこと
- imgタグはHTML標準の画像要素
- ImageはNext.jsが提供するReactコンポーネント
- Imageは端末に合った画像サイズの配信を支援する
- 画像の遅延読み込みを利用できる
- widthとheightは画像の縦横比を伝える役割もある
- public内の画像ではsrcにpublicを書かない
- 外部画像はremotePatternsで許可する
- fillを使う場合は親要素に表示領域を作る
- レスポンシブ画像ではsizesも確認する
- altには画像の内容が分かる文章を書く
<Image ... />
<img ... >
最初は、画像を一枚表示するために widthやheight、外部ドメインの設定まで必要になることを 少し複雑に感じました。
しかし、Imageは単に画像を表示するだけでなく、 画像によるページの重さや表示のずれを減らすために さまざまな情報を使っています。
表示サイズと使用場所に合った設定を選びます。