コンテンツへスキップ

3

フォントと画像の最適化

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

この章では...

以下のトピックを扱います

`next/font` を使ってカスタムフォントを追加する方法。

`next/image` を使って画像を追加する方法。

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

なぜフォントを最適化するのか?

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

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

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

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

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

カスタムの 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` の `` 要素にフォントを追加します。

/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>
  );
}

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

ブラウザを開き、開発者ツールを開いて `body` 要素を選択します。スタイルに `Inter` と `Inter_Fallback` が適用されていることを確認できます。

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

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

次にあなたの番です!`fonts.ts` ファイルで、`Lusitana` というセカンダリフォントをインポートし、それを `/app/page.tsx` ファイルの `

` 要素に渡してください。以前と同様にサブセットを指定するだけでなく、異なるフォントの**太さ**も指定する必要があります。例えば、`400`(標準)と `700`(太字)です。

準備ができたら、以下のコードスニペットを展開して解決策を確認してください。

ヒント

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

最後に、`` コンポーネントも 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"
/>

ただし、これには手動で以下のことを行う必要があります

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

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

`` コンポーネント

`` コンポーネントは HTML の `` タグを拡張したもので、次のような自動画像最適化機能を備えています

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

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

`` コンポーネントを使用しましょう。`/public` フォルダー内を見ると、`hero-desktop.png` と `hero-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>
    //...
  );
}

ここでは、`width` を `1000` ピクセル、`height` を `760` ピクセルに設定しています。レイアウトシフトを避けるために画像の `width` と `height` を設定することは良い習慣であり、これらはソース画像の縦横比と**同一**である必要があります。これらの値は、画像がレンダリングされるサイズでは*なく*、縦横比を理解するために使用される実際の画像ファイルのサイズです。

また、モバイル画面で DOM から画像を削除するための `hidden` クラスと、デスクトップ画面で画像を表示するための `md:block` クラスに気づくでしょう。

これでホームページは次のようになります

Styled home page with a custom font and hero image

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

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

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

準備ができたら、以下のコードスニペットを展開して解決策を確認してください。

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

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

章を完了しました3

Next.js を使用してフォントと画像を最適化する方法を学びました。

次のステップ

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

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