【Next.js】Imageコンポーネントnext/image(画像最適化機能)とは、WebPの場合も解説

目次

参考サイト

Next.js 13のImageコンポーネントの簡単な使い方とメリット
https://www.zenryoku-kun.com/post/nextjs13-image

画像最適化の舞台裏をのぞき見👀してnext/imageを使いこなす
https://zenn.dev/reiwatravel/articles/fb1586ea9463a1

Next.js の Image コンポーネントの使い方をまとめてみた
https://dev.classmethod.jp/articles/next-js-image-component/

Next.jsのImageコンポーネントとは?

Imageコンポーネントは、HTMLのimgタグをラップしたコンポーネントです。

HTMLのimgタグよりもNext.jsが用意したImageコンポーネントを使用することが推奨

<img> タグ <Image> コンポーネント 推奨

画像最適化

デバイスに合わせてサイズ調整、フォーマット変換、圧縮が行われます

→ファイルサイズの削減、読み込み時間の短縮

srcsetはどうする?(例)デザイナーから画像を2種(等倍1x、2倍2x)を渡されたら

下記の通りデザイナーが表示速度を考慮して1x用にWebPを、高解像度デバイス用に品質重視でPNGを用意したというケースです。

<img
  srcset="/example-400.webp 1x,
          /example-800.png 2x"
  src="/example-400.webp"
/>

Next.jsのImageコンポーネントの場合

<Image
  src="/example-800.png"  // 2x解像度の画像
  alt="画像の説明文"
  width={400}            // 1xでの表示サイズ
  height={300}           // 1xでの表示サイズ
/>

Next.jsのImageは、上記の通りサイズの大きい画像だけの使用で下記の最適化

  • WebPへの自動変換
  • 解像度の最適化

画像の表示領域をロードされる前から確保

画像の表示領域をロードされる前から確保しレイアウトシフトを防止

最適化されたレイアウトシフト防止 画像読み込み前 画像用スペース確保済み 画像読み込み後 画像表示 画像読み込み前からスペースを確保し、 レイアウトシフトを防止します
  1. Imageコンポーネントの使用:
    • next/imageからインポートして使用します。
    • 例: import Image from 'next/image'
  2. 自動最適化:
    • 画像サイズの最適化
    • フォーマットの最適化(WebPなどの最新フォーマットへの変換)
    • 遅延読み込み(Lazy Loading)の自動適用
  3. レスポンシブ対応:
    • デバイスのサイズに応じて適切な画像サイズを提供
    • sizes属性を使用してブレークポイントを指定可能
  4. ローカル画像の使用:
    • インポートした画像ファイルを直接src属性に指定可能
    • 幅と高さが自動的に検出される
  5. リモート画像の使用:
    • URL文字列をsrc属性に指定
    • width、height属性の指定が必要
  6. プレースホルダーとブラー効果:
    • placeholder="blur"を指定することで、ロード中にぼかし効果を適用可能
    • blurDataURL属性でカスタムのプレースホルダー画像を指定可能
  7. 優先度の設定:
    • priority属性を使用してLCP(Largest Contentful Paint)要素を指定可能
  8. カスタマイズ:
    • next.config.jsで画像の最適化設定をカスタマイズ可能

ローカル画像とリモート画像

ローカル画像

ローカル画像は、プロジェクト内のディレクトリに配置されます。

ビルド時に最適化されます。

import Image from 'next/image'

export default function LocalImageExample() {
  return (
    <Image
      src="/images/example.jpg"
      alt="Example image"
      width={500}
      height={300}
    />
  )
}

リモート画像

リモート画像は、外部のサーバーやサービスから動的に取得される画像です。

width、height属性の指定が必要

  • CMS(Content Management System)、CDN(Content Delivery Network)、S3などから配信される
  • アプリケーションの実行時に取得される
  • 画像の更新が容易(アプリケーションの再デプロイなしで更新可能)
import Image from 'next/image'

export default function RemoteImageExample() {
  return (
    <Image
      src="https://example.com/images/remote-image.jpg"
      alt="Remote image example"
      width={500}
      height={300}
    />
  )
}
ローカル画像 vs リモート画像 ローカル画像 ビルド時に最適化 リモート画像 実行時に最適化 最適化された画像

レスポンシブデザインでの使用

Image コンポーネントは、レスポンシブデザインにも対応しています。sizes プロパティを使用することで、異なる画面サイズに対して適切な画像サイズを指定できます。

<Image
  src="/example.jpg"
  alt="Example"
  sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
  fill
/>
Responsive Image Sizing Mobile: 100vw Tablet: 50vw Desktop: 33vw

背景画像の最適化実装

通常の画像だけでなく背景画像の最適化にも活用できます。

背景画像に Image コンポーネントを使用します。

import Image from 'next/image';

export default function BackgroundImageExample() {
  return (
    <div style={{ position: 'relative', width: '100%', height: '400px' }}>
      <Image
        src="/background-image.jpg"
        alt="背景画像"
        fill
        style={{ objectFit: 'cover' }}
      />
      <div style={{ position: 'relative', zIndex: 1 }}>
        {/* ここにコンテンツを配置 */}
        <h1>ようこそ</h1>
        <p>これは背景画像の上に表示されるコンテンツです。</p>
      </div>
    </div>
  );
}

SSGでの画像最適化

下記については変わらず使用ができます。

  • width / height によるレイアウト保持(CLS防止)
  • lazy / srcset / sizes の自動付与(軽量化・レスポンシブ対応)

Imageコンポーネントで利用する画像最適化APIは静的エクスポートでは使用できません

そのため、WebP変換やリサイズ最適化などは使用できません

DocsErrorsExport with Image Optimization API

https://nextjs.org/docs/messages/export-image-api

Next.js 16 日本語ドキュメント

https://nextjsjp.org/docs/app/guides/static-exports#%E7%94%BB%E5%83%8F%E6%9C%80%E9%81%A9%E5%8C%96

WebP/PNG の両方を x1・x2(倍密度)対応させたい場合

WebPとPNGの両方で、x1・x2それぞれの画像を適切に切り替えたい場合は、
Imageコンポーネントを使わず、下記のように記述するのが適しています。

WebPはすでに9割以上のブラウザで対応しているため、基本的にはWebPのみでも問題ないかと思います

ブラウザ検証画面のコンソール画面でconsole.log(window.devicePixelRatio);で確認できます
→1であれば非Retinaディスプレイで1x画像が表示されます

picture
│
├─ 639px以下(SP)
│   │
│   ├─ WebP対応
│   │   ├─ 高解像度(2x以上) → hero_sp@2x.webp
│   │   └─ 通常解像度(1x)   → hero_sp.webp
│   │
│   └─ WebP非対応
│       ├─ 高解像度(2x以上) → hero_sp@2x.png
│       └─ 通常解像度(1x)   → hero_sp.png
│
└─ 640px以上(PC)
    │
    ├─ WebP対応
    │   ├─ 高解像度(2x以上) → hero_pc@2x.webp
    │   └─ 通常解像度(1x)   → hero_pc.webp
    │
    └─ WebP非対応
        ├─ 高解像度(2x以上) → hero_pc@2x.png
        └─ 通常解像度(1x)   → hero_pc.png
<picture className={styles.heroImage}>
    {/* SP向け - WebP対応ブラウザ */}
    <source
        media="(max-width: 639px)"
        type="image/webp"
        srcSet={`${basePath}/img/sample/hero/hero_sp.webp 1x, ${basePath}/img/sample/hero/hero_sp@2x.webp 2x`}
    />
    {/* SP向け - 非対応ブラウザ向け(PNGフォールバック) */}
    <source
        media="(max-width: 639px)"
        type="image/png"
        srcSet={`${basePath}/img/sample/hero/hero_sp.png 1x, ${basePath}/img/sample/hero/hero_sp@2x.png 2x`}
    />
    {/* PC向け - WebP対応ブラウザ */}
    <source
        media="(min-width: 640px)"
        type="image/webp"
        srcSet={`${basePath}/img/sample/hero/hero_pc.webp 1x, ${basePath}/img/sample/hero/hero_pc@2x.webp 2x`}
    />
    {/* PC向け - 非対応ブラウザ向け(PNGフォールバック) */}
    <img
        className={styles.heroImage}
        src={`${basePath}/img/sample/hero/hero_pc.png`}
        srcSet={`${basePath}/img/sample/hero/hero_pc.png 1x, ${basePath}/img/sample/hero/hero_pc@2x.png 2x`}
        alt="サンプル画像の説明テキスト"
        loading="lazy"
    />
</picture>
パソジユ!
画像形式をWebPに完全移行しても大丈夫?【対応ブラウザの状況から考察】 ブログ・サイトの画像を、完全にWebPに移行しても大丈夫なのか??対応ブラウザの状況やパソジユデータを使って、考察してみます!

この記事を書いた人

目次