Next.js next/fontでの日本語フォントサブセット化とCLS防止設定

Next.js Performance CSS Frontend
結論

next/font を使えば自動セルフホスティングと size-adjust により CLS がゼロになります。

// Next.js公式仕様:next/font/google の設定例
import { Noto_Sans_JP } from 'next/font/google';

// ビルド時にGoogle Fontsをセルフホスティング化
const notoSansJP = Noto_Sans_JP({
  weight: ['400', '700'],
  subsets: ['latin'],
  display: 'swap',
  variable: '--font-noto-sans',
});

export default function RootLayout({ children }) {
  return (
    <html lang="ja" className={notoSansJP.variable}>
      <body>{children}</body>
    </html>
  );
}

Next.js公式仕様:next/font による最適なフォント配信

Next.js公式ドキュメント(nextjs.org/docs/app/building-your-application/optimizing/fonts)で解説されている通り、next/font を導入することで従来の <link rel="stylesheet"> による Web フォント読み込みから劇的な最適化が行われます。

  1. 完全セルフホスティング化: ビルド時にフォントファイルをローカルにDLし、fonts.gstatic.com への外部通信を完全切断
  2. 自動 size-adjust 適用: フォント読込前後でのフォントメトリクス(文字幅・高さ)の差分を自動調整し、レイアウトシフト(CLS)を物理的に防止
  3. プライバシー保護: ユーザーのIPアドレスが外部フォントサーバーへ送出されない

実際に起こる障害:日本語フォントによる FOIT (画面消滅) と重度 CLS 事故

日本語Webフォントは数千文字の漢字データを含むため、ファイルサイズが数MB単位に膨れ上がります。

最適化を行わない場合、以下の重大障害が発生します:

  • FOIT (Flash of Invisible Text): フォント読み込みが完了するまで画面のテキスト全体が透明のまま消える
  • 重度の CLS: フォント切替時にテキスト位置が下へ大きくズレて表示される

設定手順

  1. next/font/google から対象の日本語フォント(例: Noto_Sans_JP)をインポートする
  2. display: 'swap' オプションを指定し、フォント読み込み中も代替フォントでテキストを即時表示させる
  3. アプリ全体のベースフォントとして className または CSS 変数(variable)をルート <html /> タグへ適用する