Cover Image for Next.js の Local Fonts は高パフォーマンス

Next.js の Local Fonts は高パフォーマンス

NEXT.js
WordPress
PageSpeed Insights
SEO

はじめに

筆者のWebサイトは、2024年1月中旬位までは WordPress で公開していました。キャッシュを使って高速化できるのは、「WordPress に LiteSpeed Cache を利用して高速化を実現」でも紹介しました。しかし、もっと高速化したいと思いました。

そこで、Next.js をフロントとして使う構成に変える作業をしています。(筆者注:2024年1月中旬以降は Next.js アプリに代わっています)WordPress は、ヘッドレスCMS として使用して記事を書きます。記事執筆に使い勝手の良い WordPress と、サイト高速化に有利な Next.js を組み合わせる構成です。この記事は、その過程で発生したパフォーマンス問題をどうやって解決したかを紹介します。

環境について

Next.js など、変化が激しいので筆者の使用しているコンポーネントのバージョンを念のため記しておきます。使用するバージョンが異なると、この記事の結果とは異なるかもしれません。

$ npm list --depth=0 | grep -e react -e next
nextjs-wordpress@ /home/ychan/next/nextjs-wordpress
├── @fortawesome/react-fontawesome@0.2.0
├── @types/react-dom@18.2.18
├── @types/react@18.2.45
├── next@14.0.4
├── react-dom@18.2.0
├── react@18.2.0
$

Next.js のフロントアプリは、Vercel のホスティングサービスで稼働します。

Vercel にアプリをデプロイするだけで、エッジネットワークを利用でき、CDNとしても動作します。筆者の主観ですが、パフォーマンスが高く、安定していると思います。

Next.js Local Fonts を使ったきっかけ

開発中のフロントアプリを「PageSpeed Insights」でパフォーマンス確認をしてみました。デスクトップは100~99点ですが、携帯電話は 79点前後となりました。携帯電話のパフォーマンスを改善しようと思いました。

PageSpeed Insight は、改善できる項目を教えてくれます。親切ですね。

指摘された CSS ファイルを調べてみました。この CSS ファイルは、フォント情報が大部分で未使用部分が多い事が分かりました。しかし、なぜデスクトップでは問題なくて、携帯だと問題になるのか?筆者は通信速度の違いのせいと考えています(間違っているかもしれませんが)。次のキャプチャ画像の左側が携帯、右側がデスクトップです。通信速度がかなり違います。

筆者は Webフォント(Google Fonts)を導入しています。Next の公式ドキュメントには、フォントの最適化について説明があります。もう一度良く読んでみると、Local Fonts についても記述があったので、この方式に変更したところパフォーマンス問題は解決しました。何やら良く分かっていなくて申し訳ないですが、ともかくレンダリングブロックは解消できました。

筆者の Local Fonts 利用方法紹介

変更前と変更後のサンプルソースコードを示します。

変更前 (app/layout.tsx)

import { Noto_Sans_JP } from 'next/font/google'

const myFont = Noto_Sans_JP ({
  subsets: ['latin'],
  display: 'swap',
})

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

変更後 (app/layout.tsx)

import localFont from 'next/font/local'

const myFont = localFont({
  src: './noto-serif-jp-v21-latin-regular.woff2',
  display: 'swap',
})

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

ローカルフォントファイルは、以下から入手しました。

google-webfonts-helper

A Hassle-Free Way to Self-Host Google Fonts

https://gwfh.mranftl.com/fonts

zipファイルでダウンロードできるので、解凍したフォントファイルをサーバーに置きます。サンプルコードでは、app ディレクトリ直下に noto-serif-jp-v21-latin-regular.woff2 を置いています。

計測結果

Local Fonts 導入で、携帯スコア100点のキャプチャは次になります。

Local Fonts 適用後の感想

Web開発ツールの「カバレッジ」で、Local Fonts 導入前後を比較すると、導入後では CSS ファイルの最適化が良く出来ていると思いました。CSS ファイルのサイズ自体がだいぶ小さくなり、かつ未使用部分も少なく無駄がないという感じです。筆者が持っているガラホ(INFOBAR)でサイトを見ると、導入後は少し速くなったように感じました。

【おまけ】本記事のアイキャッチ

この記事のアイキャッチは、実家で元気に過ごしている「さくら」です。記事内容とは全く関係ありません。

ある日、捨て猫だった「さくら」を筆者の父が拾ってきました。筆者は別のところに住んでいたので、当時のことは良く知りませんが、生まれたばかりの子猫を哺乳瓶などを使って育てました。撮影は、良く世話をした姪っ子です。筆者がサイトを開設したので写真提供してもらいました。今はすっかり大人猫に成長しています。椅子に寝そべるのが好きなようで、筆者が座ろうとする椅子に寝そべっていたりします。可愛がられていて、さくらは幸せ猫ですね。


More Stories

Cover Image for Tailwind CSS でダークモードを実装してみた

Tailwind CSS でダークモードを実装してみた

NEXT.js
SvelteKit
Web草紙
Tailwind CSS

筆者の Blog サイトでダークモードを実装した紹介です。Next.js と SvelteKit での実装について説明しています。SvelteKit については、日本語の情報量が少ないようだったので筆者の実装についてざっと説明しています。

Cover Image for Svelte / SvelteKit で Font Awesome を使ってみる

Svelte / SvelteKit で Font Awesome を使ってみる

SvelteKit
Font Awesome
svelte-fa

Svelte/SvelteKit で Font Awesome を利用する方法を紹介します。svelte-fa パッケージを利用して実装してみました。結構簡単に実装できると思うのでお勧めです。