メインコンテンツまでスキップ

画像とフォントを最適化する方法

Next.jsには、パフォーマンスとユーザーエクスペリエンスを向上させるための自動画像およびフォント最適化機能が備わっています。このページでは、それらの使い方を説明します。

静的アセットの取り扱い

画像やフォントなどの静的ファイルは、ルートディレクトリ内のpublicというフォルダに保存できます。public内のファイルは、ベースURL(/)から始まるコードで参照できます。

appフォルダとpublicフォルダを示すフォルダ構造appフォルダとpublicフォルダを示すフォルダ構造

画像の最適化

Next.jsの<Image>コンポーネントは、HTMLの<img>要素を拡張して以下を提供します:

  • サイズの最適化: WebPやAVIFなどの最新の画像フォーマットを使用して、各デバイスに適したサイズの画像を自動的に提供します
  • 視覚的安定性: 画像の読み込み時にレイアウトシフトを自動的に防ぎます
  • 高速なページ読み込み: ネイティブブラウザの遅延読み込みを使用して、画像がビューポートに入ったときにのみ画像を読み込み、オプションでぼかしプレースホルダーを使用します
  • アセットの柔軟性: リモートサーバーに保存されている画像でも、オンデマンドで画像をリサイズします

<Image>を使用するには、next/imageからインポートし、コンポーネント内でレンダリングします。

app/page.tsx
import Image from 'next/image'

export default function Page() {
return <Image src="" alt="" />
}

srcプロパティは、ローカルまたはリモートの画像にすることができます。

ローカル画像

ローカル画像を使用するには、publicフォルダから.jpg.png、または.webp画像ファイルをimportします。

app/page.tsx
import Image from 'next/image'
import profilePic from './me.png'

export default function Page() {
return (
<Image
src={profilePic}
alt="著者の写真"
// width={500} 自動的に提供されます
// height={500} 自動的に提供されます
// blurDataURL="data:..." 自動的に提供されます
// placeholder="blur" // 読み込み中のオプションのぼかし
/>
)
}

Next.jsは、インポートされたファイルに基づいて画像の本来のwidthheightを自動的に決定します。これらの値は、画像の比率を決定し、画像の読み込み中にCumulative Layout Shiftを防ぐために使用されます。

リモート画像

リモート画像を使用するには、srcプロパティにURL文字列を指定できます。

app/page.tsx
import Image from 'next/image'

export default function Page() {
return (
<Image
src="https://s3.amazonaws.com/my-bucket/profile.png"
alt="著者の写真"
width={500}
height={500}
/>
)
}

Next.jsはビルドプロセス中にリモートファイルにアクセスできないため、widthheight、およびオプションのblurDataURL propsを手動で指定する必要があります。widthheight属性は、画像の正しいアスペクト比を推測し、画像の読み込みによるレイアウトシフトを避けるために使用されます。

次に、リモートサーバーからの画像を安全に許可するために、next.config.jsでサポートされるURLパターンのリストを定義する必要があります。悪意のある使用を防ぐために、できるだけ具体的にしてください。たとえば、次の設定では、特定のAWS S3バケットからの画像のみを許可します:

next.config.ts
import { NextConfig } from 'next'

const config: NextConfig = {
images: {
remotePatterns: [
{
protocol: 'https',
hostname: 's3.amazonaws.com',
port: '',
pathname: '/my-bucket/**',
search: '',
},
],
},
}

export default config

フォントの最適化

next/fontモジュールは、フォントを自動的に最適化し、外部ネットワークリクエストを削除してプライバシーとパフォーマンスを向上させます。

これは、任意のフォントファイルに対する組み込みの自動セルフホスティングを含んでいます。これにより、レイアウトシフトなしでWebフォントを最適に読み込むことができます。

next/fontを使用するには、next/font/localまたはnext/font/googleからインポートし、適切なオプションで関数として呼び出し、フォントを適用したい要素のclassNameを設定します。例:

app/layout.tsx
import { Geist } from 'next/font/google'

const geist = Geist({
subsets: ['latin'],
})

export default function Layout({ children }: { children: React.ReactNode }) {
return (
<html lang="en" className={geist.className}>
<body>{children}</body>
</html>
)
}

Googleフォント

任意のGoogleフォントを自動的にセルフホストできます。フォントはデプロイメントに含まれ、デプロイメントと同じドメインから提供されるため、ユーザーがサイトを訪問したときにブラウザからGoogleへのリクエストは送信されません。

Googleフォントを使用するには、next/font/googleから選択したフォントをインポートします:

app/layout.tsx
import { Geist } from 'next/font/google'

const geist = Geist({
subsets: ['latin'],
})

export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en" className={geist.className}>
<body>{children}</body>
</html>
)
}

最適なパフォーマンスと柔軟性を得るために、可変フォントを使用することをお勧めします。ただし、可変フォントを使用できない場合は、ウェイトを指定する必要があります

app/layout.tsx
import { Roboto } from 'next/font/google'

const roboto = Roboto({
weight: '400',
subsets: ['latin'],
})

export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en" className={roboto.className}>
<body>{children}</body>
</html>
)
}

ローカルフォント

ローカルフォントを使用するには、next/font/localからフォントをインポートし、publicフォルダ内のローカルフォントファイルのsrcを指定します。

app/layout.tsx
import localFont from 'next/font/local'

const myFont = localFont({
src: './my-font.woff2',
})

export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en" className={myFont.className}>
<body>{children}</body>
</html>
)
}

単一のフォントファミリーに対して複数のファイルを使用したい場合、srcは配列にすることができます:

const roboto = localFont({
src: [
{
path: './Roboto-Regular.woff2',
weight: '400',
style: 'normal',
},
{
path: './Roboto-Italic.woff2',
weight: '400',
style: 'italic',
},
{
path: './Roboto-Bold.woff2',
weight: '700',
style: 'normal',
},
{
path: './Roboto-BoldItalic.woff2',
weight: '700',
style: 'italic',
},
],
})