【Next.js和訳】Basic Features/Image Optimization
この記事について
この記事は、Basic Features/Image Optimizationの記事を和訳したものです。
記事内で使用する画像は、公式ドキュメント内の画像を引用して使用させていただいております。
画像コンポーネントと画像の最適化
バージョン10.0.0以降、Next.js には Image Component と Automatic Image Optimization が組み込まれています。
Next.js の Image Component(next/image
)は、HTML の<img>
要素を拡張したもので、現代のウェブ用に進化しています。
自動画像最適化では、ブラウザがサポートしている場合、WebPなどの最新フォーマットで画像をリサイズ、最適化して提供します。これにより、ビューポートが小さいデバイスに大きな画像を配信することがなくなります。また、Next.js は将来の画像フォーマットを自動的に採用し、それらのフォーマットをサポートするブラウザに提供することができます。
自動画像最適化は、どんな画像ソースにも対応します。画像が CMS などの外部データソースでホストされている場合でも、画像を最適化することができます。
Next.js は、構築時に画像を最適化するのではなく、ユーザーからのリクエストに応じて、オンデマンドで画像を最適化します。静的サイトジェネレーターや静的サイトのみのソリューションとは異なり、10 枚の画像でも 1,000 万枚の画像でも、ビルド時間は長くなりません。
画像はデフォルトでレイジーロードされます。つまり、ビューポートの外側にある画像に対して、ページスピードが低下することはありません。画像は、ビューポートにスクロールされたときに読み込まれます。
画像は、Google が検索ランキングで使用しているCore Web VitalであるCumulative Layout Shiftを避けるように、常にレンダリングされます。
画像コンポーネント
アプリケーションに画像を追加するには、next/image
コンポーネントをインポートします。
import Image from "next/image"
function Home() {
return (
<>
<h1>My Homepage</h1>
<Image src="/me.png" alt="Picture of the author" width={500} height={500} />
<p>Welcome to my homepage!</p>
</>
)
}
export default Home
画像のインポート
プロジェクト内に存在する画像をimport
することができます。(require
はサポートされていません。import
のみです。)
直接import
する場合は、width
、height
、blurDataURL
が自動的に画像コンポーネントに提供されます。Alt テキストは別途必要です。
import Image from "next/image"
import profilePic from "../public/me.png"
function Home() {
return (
<>
<h1>My Homepage</h1>
<Image
src={profilePic}
alt="Picture of the author"
// width={500} 自動的に指定される
// height={500} 自動的に指定される
// blurDataURL="data:..." 自動的に指定される
// オプションで、ロード中に画像のぼかしバージョンを追加することができます
// placeholder="blur"
/>
<p>Welcome to my homepage!</p>
</>
)
}
ダイナミックイメージやリモートイメージの場合は、width
、height
、blurDataURL
を手動で指定する必要があります。
プロパティ
next/image
コンポーネントで利用可能なすべてのプロパティを表示します。
構成
next/image
コンポーネントで利用可能なプロパティに加えて、オプションとして、next.config.js
を介して、より高度なユースケースのために画像最適化を設定することができます。
ドメイン
外部のウェブサイトでホストされている画像に対して画像最適化を有効にするには、画像のsrc
に絶対 URL を使用し、最適化を許可するdomeins
を指定します。これは、外部 URL が悪用されないようにするために必要です。loader
が外部イメージサービスに設定されている場合、このオプションは無視されます。
module.exports = {
images: {
domains: ["example.com"],
},
}
ローダー
Next.js に内蔵されている画像最適化機能を使わずに、クラウドプロバイダーを使って画像を最適化したい場合は、ローダーとパスのプレフィックスを設定できます。これにより、画像のsrc
に相対 URL を使用しても、プロバイダー用の正しい絶対 URL を自動的に生成することができます。
module.exports = {
images: {
loader: "imgix",
path: "https://example.com/myaccount/",
},
}
以下の Image Optimization のクラウドプロバイダーが含まれます。
- Vercel: Vercel にデプロイすると自動的に動作し、設定は不要です。詳細はこちら
-
Imgix:
loader
:imgix
-
Cloudinary:
loader
:cloudinary
-
Akamai:
loader
:Akamai
- Custom:
loader
:custom
next/image
コンポーネントにloader
prop を実装することで、カスタムクラウドプロバイダーを使用します。 - デフォルト。
next dev
、next start
、またはカスタムサーバーで自動的に動作します。
別のプロバイダーが必要な場合は、next/image
で loader
prop を使用できます。
キャッシング
ここでは、デフォルトローダーのキャッシングアルゴリズムについて説明します。その他のloaderについては、クラウドプロバイダーのドキュメントを参照してください。
画像はリクエストに応じて動的に最適化され、<distDir>/cache/images
ディレクトリに保存されます。最適化された画像ファイルは、その後のリクエストに対して、有効期限に達するまで提供されます。キャッシュされているが期限切れのファイルにマッチするリクエストがあると、新しい最適化された画像を生成して新しいファイルをキャッシュする前に、キャッシュされたファイルが削除されます。
有効期限(というか Max Age)は、上流のサーバーのCache-Control
ヘッダーで定義されます。
Cache-Control
に s-maxage
がある場合は、それが使用されます。s-maxage
が見つからない場合は、max-age
が使用されます。max-age
が見つからない場合は、minimumCacheTTL
が使用されます。
アップストリームイメージにmax-age
が含まれていない場合、minimumCacheTTL
を設定してキャッシュ期間を長くすることができます。
また、deviceSizes
および imageSizes
を設定して、生成可能なイメージの総数を減らすこともできます。
上級者向け
以下の設定は、高度なユースケースのためのもので、通常は必要ありません。以下のプロパティを設定した場合、今後のアップデートで Next.js のデフォルトが変更されても上書きされます。
デバイスサイズ
ウェブサイトのユーザーから予想されるデバイス幅がわかっている場合、deviceSizes
プロパティを使ってデバイス幅のブレイクポイントのリストを指定することができます。これらの幅は、next/image
コンポーネントがlayout="responsive
"またはlayout="fill"
を使用する際に使用され、ウェブサイトにアクセスするデバイスに対して正しい画像が提供されるようになります。
何も設定されていない場合は、以下のデフォルト値が使用されます。
module.exports = {
images: {
deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048, 3840],
},
}
画像サイズ
imageSizes
プロパティを使って、画像の幅のリストを指定することができます。これらの幅は、配列が連結されるため、deviceSizes
で定義された幅とは異なる(通常は小さい)必要があります。これらの幅は、next/image
コンポーネントでlayout="fixed"
またはlayout="intrinsic"
が使用されている場合に使用されます。
設定がなされていない場合は、以下のデフォルトが使用されます。
module.exports = {
images: {
imageSizes: [16, 32, 48, 64, 96, 128, 256, 384],
},
}
最小キャッシュ TTL
最適化された画像をキャッシュする際の TTL(Time To Live)を秒単位で設定できます。多くの場合、ファイルの内容をハッシュ化して永久にキャッシュするスタティックイメージインポートを使用した方が良いでしょう。
module.exports = {
images: {
minimumCacheTTL: 60,
},
}
ブラウザに Cache-Control
ヘッダを追加する必要がある場合(推奨しません)、/_next/image
自体ではなく、/some-asset.jpg
などのアップストリーム画像にheaders
を設定することができます。
静的インポートの無効化
デフォルトの動作では、import icon from './icon.png
として、それをsrc
プロパティに渡すといった静的ファイルのインポートが可能です。
しかし、インポート時に異なる動作をする他のプラグインと競合する場合、この機能を無効にしたい場合があります。
以下の設定を行うことで、静止画像のインポートを無効にすることができます。
module.exports = {
images: {
disableStaticImages: true,
},
}
関連
次に何をすべきかについては、以下のセクションをお勧めします。
Discussion