
Next.jsのパフォーマンスを最大化するためにできること
今回は、Next.jsの特徴を活かしつつ、サイト全体のパフォーマンスを最大化するために出来ること気を付けることをみていきたいと思います。
特徴の一つとして、Next.jsでは、サーバー上でレンダリングされるSSRがデフォルトとなっています。
このサーバー側とクライアント側のコンポーネントの組み合わせ方によっても、パフォーマンスに大きく影響してしまいますので、注意点を交えながら、見ていきたと思います。
Server Componentを積極的に利用
Next.jsでは、クライアントサイドでレンダリングされるClient ComponentとサーバーサイドでレンダリングされるServer Componentを利用することができます。しかし、パフォーマンスの向上のために、Client Componentは、無闇に多用せず、Server Component利用がNext.js上、推奨されています。
その理由として、下記が大きなメリットとして挙げられます。
データフェッチが高速になる
サーバー側のレンダリングサイズされるので、JSバンドルサイズが削減される(JSバンドルサイズ=クライアント側で処理するJSの総量)
SEOの向上
セキュリティの強化
サーバー側でレンダリングされるため、表示速度への好影響はもちろん、HTML状態でクライアント側に表示されるため、SEOの向上もあります。
処理がサーバー側で実行されるため、クライアント側でのAPIキーなどの情報が漏洩されにくくなりセキュリティの強化にも繋がります。
<注意点>
状況によって、クライアント側で処理を行う Client Componentを利用したい場合があると思います。
しかし、親子要素を持つ構成の場合、親のコンポーネントがClient Componentになった場合、その子コンポーネントも自動的にClient Componentになってしまう点は要注意です。
下記の図で解説していきます。

先ほど説明した点で、この中間コンポーネントで、Client Componentを使用してしまうと、その下のコンポーネントも全てClient Componentになってしまいますので、コンポーネントでデータフェッチができないなど予期しないエラーが発生してしまいます。
ここで分かる通り、最上位の位置に該当する、page.tsxやlayout.tsxなは、必ずサーバーでレンダリングさせる必要があるため、Client Componentに変更する「use client」の記述をページ側に設定しないように注意しましょう。
フォントの最適化
Next.jsには、next/fontを利用したWebフォントの最適化機能があります。
特にGoogle Fontsを直接組み込むnext/font/googleを活用すると、Google Fontsを簡単に利用でき、ビルド時にフォントファイルがダウンロードされてセルフホストされるため、ブラウザがGoogleのサーバーへリクエストを送る必要がなくなり、ページの読み込み速度が向上します。
import { Noto_Sans_JP } from "next/font/google";
export const notoSansJp = Noto_Sans_JP({
subsets: ["latin"],
weight: ["400", "700"],
display: "swap",
variable: "--font-noto-sans-jp",
});
上記が、Google Fontsを利用したコードです。サブセット化の指定や、weightの指定を行うことができます。
weightもサイト上での使用分だけ指定することが大切になっていきます。
サブセットの指定 : subsets: ['latin'] で最小限の文字セットを読み込むことで、不要なデータを減らす
display: 'swap' の設定 : フォントの遅延読み込みを許可
variableの設定 : CSS内での利用するためのプロパティを指定が可能
Localフォントを使用する
Next.jsでは、Google fonts以外のLocalフォントの使用の際にも、CSSの@font-face を定義する必要がなくなる独自機能を持っています。
それが、next/font/localを使う方法です。これをimportすることで、ローカルフォントを簡単に Next.js に適用が可能になります。
import localFont from "next/font/local";
// フォントを定義
export const myFont = localFont({
src: [
{
path: "../fonts/MyFont.woff2", // フォントファイルのパス
weight: "400",
style: "normal",
},
{
path: "../fonts/MyFont-Bold.woff2",// フォントファイルのパス
weight: "700",
style: "normal",
},
{
path: "../fonts/MyFont-Italic.woff2",// フォントファイルのパス
weight: "400",
style: "italic",
},
],
variable: "--font-myFont", // CSS変数として定義(オプション)
display: "swap", // フォントの表示方法
});
Google fontsを使用した時と同様に、src、variable、displayの指定が可能になります。
そして、使用するページ側で下記の設定をしたり、variableを用いて、CSS側に記述追加を行うことで設定が完了します。
import { myFont } from "@/libs/fonts"
import { Header } from "./components/Header";
import { Footer } from "./components/Footer";
export default function RootLayout({ children }) {
return (
<html lang="ja">
<body className={`${myFont.variable}`}>
<Header />
<main>{children}</main>
<Footer />
</body>
</html>
);
}
コードの分割と遅延読み込み
Next.jsの機能である、next/dynamicを活用すると、特定のコンポーネントを遅延読み込みして初期ロードの負担を軽減できます。
サーバーサイドレンダリング(SSR)との統合が可能で、サーバーサイドレンダリングを有効または無効にすることも指定ができます。
import dynamic from 'next/dynamic';
const HeavyComponent = dynamic(() => import('./HeavyComponent'), { ssr: false });
export default function Page() {
return (
<div>
<HeavyComponent />
</div>
);
}
画像の最適化
こちらは別記事で解説しておりますが、next/imageを使用して、画像を最適化できる機能がNext.jsに備わっていますので、積極的に利用するようにしましょう。
まとめ
Next.jsの特徴を活用しつつ、WEBサイトのパフォーマンスをより向上していくためにできることを解説していきました。
動的にデータを表示したいなど、要件によって、複雑化されてくる部分もあるかと思いますが、しっかりと特徴を理解した上で、最適なサイト構築をしていきたいと改めて思いました。
皆さんのNext.js構築に参考になれば幸いです。