コンテンツへスキップ

3

フォントと画像の最適化

前の章では、Next.js アプリケーションのスタイル設定方法を学習しました。カスタムフォントとヒーロー画像を追加することで、ホームページの作業を続けましょう。

この章では…

取り上げるトピックは以下のとおりです。

next/font を使用したカスタムフォントの追加方法。

next/image を使用した画像の追加方法。

Next.js でフォントと画像がどのように最適化されるか。

フォントを最適化する理由

フォントはウェブサイトのデザインにおいて重要な役割を果たしますが、プロジェクトでカスタムフォントを使用すると、フォントファイルの取得と読み込みが必要な場合、パフォーマンスに影響を与える可能性があります。

累積レイアウトシフト は、Google がウェブサイトのパフォーマンスとユーザーエクスペリエンスを評価するために使用する指標です。フォントの場合、ブラウザが最初にフォールバックフォントまたはシステムフォントでテキストをレンダリングし、読み込みが完了したらカスタムフォントに置き換えるときに、レイアウトシフトが発生します。この置き換えにより、テキストサイズ、間隔、またはレイアウトが変更され、周囲の要素がシフトする可能性があります。

Mock UI showing initial load of a page, followed by a layout shift as the custom font loads.

next/font モジュールを使用すると、Next.js はアプリケーション内のフォントを自動的に最適化します。ビルド時にフォントファイルをダウンロードし、他の静的アセットと共にホストします。つまり、ユーザーがアプリケーションにアクセスすると、パフォーマンスに影響を与える可能性のあるフォントに対する追加のネットワークリクエストはありません。

プライマリフォントの追加

それでは、これがどのように機能するかを確認するために、カスタムGoogleフォントをアプリケーションに追加してみましょう!

/app/ui フォルダーに、fonts.ts という名前の新しいファイルを作成します。このファイルを使用して、アプリケーション全体で使用されるフォントを保持します。

next/font/google モジュールから Inter フォントをインポートします。これがプライマリフォントになります。次に、読み込むサブセットを指定します。この場合は、'latin'

/app/ui/fonts.ts
import { Inter } from 'next/font/google';
 
export const inter = Inter({ subsets: ['latin'] });

最後に、/app/layout.tsx<body> 要素にフォントを追加します。

/app/layout.tsx
import '@/app/ui/global.css';
import { inter } from '@/app/ui/fonts';
 
export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body className={`${inter.className} antialiased`}>{children}</body>
    </html>
  );
}

<body> 要素に Inter を追加することで、フォントがアプリケーション全体に適用されます。ここでは、フォントを滑らかにするTailwindのantialiasedクラスも追加しています。このクラスを使用する必要はありませんが、良い効果があります。

ブラウザに移動し、開発ツールを開いて body 要素を選択します。「スタイル」の下に InterInter_Fallback が適用されているはずです。

練習:セカンダリフォントの追加

アプリケーションの特定の要素にフォントを追加することもできます。

さあ、あなたの番です!fonts.ts ファイルで、Lusitana というセカンダリフォントをインポートし、/app/page.tsx ファイルの <p> 要素に渡します。前に行ったようにサブセットを指定するだけでなく、フォントの**ウェイト**も指定する必要があります。

準備ができたら、下のコードスニペットを展開してソリューションを確認してください。

ヒント

  • フォントに渡すウェイトオプションが不明な場合は、コードエディターのTypeScriptエラーを確認してください。
  • Google FontsウェブサイトにアクセスしてLusitanaを検索し、利用可能なオプションを確認してください。
  • 複数のフォントの追加についてはドキュメント、オプションの完全なリストについてはこちらを参照してください。

最後に、<AcmeLogo /> コンポーネントも Lusitana を使用しています。エラーを防ぐためにコメントアウトされていましたが、ここでコメントアウトを解除できます。

/app/page.tsx
// ...
 
export default function Page() {
  return (
    <main className="flex min-h-screen flex-col p-6">
      <div className="flex h-20 shrink-0 items-end rounded-lg bg-blue-500 p-4 md:h-52">
        <AcmeLogo />
        {/* ... */}
      </div>
    </main>
  );
}

素晴らしい!アプリケーションに2つのカスタムフォントを追加しました!次に、ホームページにヒーロー画像を追加しましょう。

画像を最適化する理由

Next.js は、最上位レベルの/public フォルダーにある画像などの**静的アセット**を提供できます。/public 内のファイルは、アプリケーション内で参照できます。

通常のHTMLでは、次のように画像を追加します。

<img
  src="/hero.png"
  alt="Screenshots of the dashboard project showing desktop version"
/>

ただし、これには手動で

  • さまざまな画面サイズで画像がレスポンシブであることを確認する必要があります。
  • さまざまなデバイスの画像サイズを指定する必要があります。
  • 画像の読み込みによるレイアウトシフトを防ぐ必要があります。
  • ユーザーのビューポートの外にある画像を遅延読み込みする必要があります。

画像の最適化は、Web開発における大きなトピックであり、それ自体が専門分野と見なされる可能性があります。これらの最適化を手動で実装する代わりに、next/image コンポーネントを使用して画像を自動的に最適化できます。

<Image> コンポーネント

<Image>コンポーネントは、HTMLの<img>タグを拡張したもので、以下の様な自動画像最適化機能を備えています。

  • 画像の読み込み時にレイアウトシフトを自動的に防止します。
  • ビューポートが小さいデバイスに大きな画像を送信しないよう、画像のサイズを調整します。
  • デフォルトで遅延読み込みが有効になっています(画像がビューポートに入ってきた時に読み込まれます)。
  • ブラウザがサポートしている場合、WebPAVIFなど、最新のフォーマットで画像を提供します。

デスクトップのヒーロー画像の追加

<Image>コンポーネントを使用してみましょう。/publicフォルダの中を見ると、hero-desktop.pnghero-mobile.pngという2つの画像があることがわかります。これら2つの画像は全く異なるもので、ユーザーのデバイスがデスクトップかモバイルかによって表示が変わります。

/app/page.tsxファイルで、next/imageからコンポーネントをインポートします。その後、コメントの下に画像を追加します。

/app/page.tsx
import AcmeLogo from '@/app/ui/acme-logo';
import { ArrowRightIcon } from '@heroicons/react/24/outline';
import Link from 'next/link';
import { lusitana } from '@/app/ui/fonts';
import Image from 'next/image';
 
export default function Page() {
  return (
    // ...
    <div className="flex items-center justify-center p-6 md:w-3/5 md:px-28 md:py-12">
      {/* Add Hero Images Here */}
      <Image
        src="/hero-desktop.png"
        width={1000}
        height={760}
        className="hidden md:block"
        alt="Screenshots of the dashboard project showing desktop version"
      />
    </div>
    //...
  );
}

ここでは、width1000height760ピクセルに設定しています。レイアウトシフトを避けるために、画像のwidthheightを設定するのは良い習慣です。これらの値は、ソース画像と**同一の**アスペクト比である必要があります。

モバイル画面では画像をDOMから削除するためにhiddenクラス、デスクトップ画面で画像を表示するためにmd:blockクラスも使用していることに注目してください。

ホームページはこれで次のようになるはずです。

Styled home page with a custom font and hero image

練習:モバイルヒーロー画像の追加

さあ、あなたの番です!今追加した画像の下に、hero-mobile.png用の別の<Image>コンポーネントを追加してください。

  • 画像のwidth560height620ピクセルに設定してください。
  • モバイル画面では表示し、デスクトップ画面では非表示にする必要があります。開発者ツールを使用して、デスクトップ画像とモバイル画像が正しく入れ替わっているかどうかを確認できます。

準備ができたら、下のコードスニペットを展開してソリューションを確認してください。

素晴らしい!ホームページにカスタムフォントとヒーロー画像が追加されました。

これらのトピックについては、リモート画像の最適化やローカルフォントファイルの使用など、さらに学ぶべきことがたくさんあります。フォントと画像についてさらに詳しく知りたい場合は、以下を参照してください。

チャプター完了3

Next.jsを使用したフォントと画像の最適化方法を学習しました。

次へ

4: レイアウトとページの作成

ネストされたレイアウトとページを使用して、ダッシュボードルートを作成しましょう!