モダンなWebアプリケーションでは、表示速度と開発効率の両立が重要です。
Reactをベースにした Next.js は、SSR、SSG、画像最適化、ルーティング、キャッシュなど、Webパフォーマンスを改善するための仕組みを多く備えています。
しかし、Next.jsを採用しただけで自動的に高速なWebサイトになるわけではありません。
本記事では、Next.jsを使って高速なWebアプリケーションを構築する際に意識したいポイントを紹介します。
1. Server Componentを活用する
Next.jsのApp Routerでは、Server Componentを基本として利用できます。
Server Componentのメリットは、不要なJavaScriptをブラウザへ送信せずに済むことです。
例えば、単純なデータ表示であればClient Componentにする必要はありません。
export default async function Page() {
const data = await getData();
return (
<main>
<h1>{data.title}</h1>
<p>{data.description}</p>
</main>
);
}
このような処理はサーバー側で実行されるため、クライアント側のJavaScript量を減らせます。
2. "use client"を必要な場所だけに使う
Next.jsでは、インタラクティブな処理が必要な場合に、
"use client";
を指定します。
例えばボタン操作やState管理などです。
"use client";
import { useState } from "react";
export default function Counter() {
const [count, setCount] = useState(0);
return (
<button onClick={() => setCount(count + 1)}>
{count}
</button>
);
}
便利ですが、ページ全体をClient Componentにすると、JavaScript Bundleが大きくなる可能性があります。
そのため、
Server Component
↓
必要な部分だけClient Component
という構成がおすすめです。
3. next/imageを利用する
Webパフォーマンスでは画像最適化が非常に重要です。
Next.jsではnext/imageを利用できます。
import Image from "next/image";
export default function Hero() {
return (
<Image
src="/hero.webp"
width={1200}
height={675}
alt="Hero image"
priority
/>
);
}
Imageコンポーネントを利用すると、
- 適切なサイズへの変換
- Lazy Loading
- レスポンシブ配信
- レイアウトシフトの軽減
などを実現しやすくなります。
ただし、すべての画像にpriorityを指定するのは避けます。
ファーストビューの重要な画像だけに利用する方がよいでしょう。
4. Dynamic Importで初期Bundleを小さくする
初期表示で必要のない機能は、Dynamic Importを利用して後から読み込めます。
import dynamic from "next/dynamic";
const Chart = dynamic(
() => import("./Chart"),
{
loading: () => <p>Loading...</p>
}
);
例えば、
- グラフ
- モーダル
- 管理画面
- 高機能エディタ
などは、ページ読み込み時には必要ない場合があります。
必要なタイミングで読み込むことで、初期JavaScriptを減らせます。
5. データ取得とキャッシュを考える
Next.jsでは、データ取得方法もパフォーマンスに大きく影響します。
毎回同じデータをサーバーから取得する場合、不必要な負荷が発生します。
変更頻度が低いデータでは、キャッシュを活用できます。
const data = await fetch(
"https://api.example.com/articles",
{
next: {
revalidate: 300
}
}
);
この例では、一定時間キャッシュを利用できます。
データの性質によって、
リアルタイム性が高い
→ Dynamic
更新頻度が低い
→ Cache / Revalidation
のように使い分けることが重要です。
6. Static Renderingを活用する
すべてのページを毎回サーバー側で生成する必要はありません。
例えば、
- Aboutページ
- FAQ
- 技術ドキュメント
- 固定コンテンツ
などはStatic Renderingに向いています。
静的ページは事前生成できるため、ユーザーへ高速に配信できます。
CDNとの相性も良くなります。
7. Font Optimization
Webフォントもパフォーマンスに影響します。
Next.jsではnext/fontを利用できます。
import { Inter } from "next/font/google";
const inter = Inter({
subsets: ["latin"]
});
export default function Layout({
children
}) {
return (
<html className={inter.className}>
<body>{children}</body>
</html>
);
}
フォント読み込みを最適化することで、
- Layout Shift
- 外部リクエスト
- Font Loading
などを改善できます。
8. Middlewareを使いすぎない
Middlewareは便利ですが、すべてのリクエストで複雑な処理を行うとレスポンス時間へ影響する可能性があります。
例えば、
Authentication
Redirect
Locale
Access Control
など、本当に必要な処理だけに限定するのが理想です。
複雑なデータベース処理をMiddlewareへ入れるのは避けた方がよいケースがあります。
9. JavaScript Bundleを確認する
便利なライブラリを追加し続けると、Bundleサイズが徐々に増えていきます。
例えば、大きなライブラリを1つの機能のためだけに導入すると、初期ロードが重くなる場合があります。
確認すべきポイントは、
- 不要な依存関係
- 重複ライブラリ
- 大きなUIライブラリ
- 未使用コード
です。
定期的にBundle Analyzerなどを使って確認するとよいでしょう。
10. API Routeの処理時間を確認する
フロントエンドが高速でも、APIが遅ければユーザー体験は悪化します。
API Routeでは、
- Database Query
- 外部API
- JSON変換
- Authentication
などがボトルネックになる場合があります。
例えば、複数のAPIを順番に呼び出すより、
const [user, content] = await Promise.all([
getUser(),
getContent()
]);
のように、並列実行できる処理はまとめることで待ち時間を短縮できます。
11. Core Web Vitalsを確認する
Next.jsの最適化では、最終的に実際のユーザー体験を測定することが重要です。
主に確認したいのは、
- LCP
- INP
- CLS
です。
特に、
LCP
→ Hero Image / Server Response
INP
→ JavaScript / Event Processing
CLS
→ Image / Font / Dynamic Content
という関係を確認すると、原因を探しやすくなります。
デジタルプラットフォームでの活用例
モバイルユーザーが多いデジタルサービスでは、フロントエンドのJavaScript量や画像サイズがユーザー体験へ直接影響します。
例えば、WOW88 のようなモバイル利用を意識したデジタルプラットフォームを技術的なケースとして考える場合でも、Server Component、画像最適化、Dynamic Import、キャッシュなどを適切に組み合わせることで、初期表示の軽量化を検討できます。
重要なのは「Next.jsを使っているから高速」と考えるのではなく、実際の利用環境で継続的に測定することです。
パフォーマンス改善の基本フロー
Next.jsプロジェクトでは、次の流れで改善すると整理しやすくなります。
Lighthouse / DevTools
↓
問題を特定
↓
Bundle・Image・APIを確認
↓
最適化
↓
再測定
↓
本番環境で確認
例えば、
LCPが遅い
↓
Hero Imageを確認
↓
next/imageを利用
↓
priorityを設定
↓
再測定
というように、1つずつ改善すると効果を判断しやすくなります。
よくある失敗
すべてClient Componentにする
Reactに慣れていると、ページ全体へ"use client"を設定したくなる場合があります。
しかし、不要なJavaScript増加につながる可能性があります。
大きなライブラリを安易に追加する
数行の処理のために大規模なライブラリを導入すると、Bundleが増える可能性があります。
キャッシュを使わない
毎回同じAPIやデータベースへアクセスすると、サーバー負荷とレスポンス時間が増加します。
Lighthouseの点数だけを見る
Performance Scoreだけでは、実際のユーザー体験を完全には判断できません。
本番データも合わせて確認する必要があります。
まとめ
Next.jsには、高速なWebアプリケーションを作るための機能が多く用意されています。
特に重要なのは、
- Server Componentを活用する
- Client Componentを必要最小限にする
- next/imageで画像を最適化する
- Dynamic Importを使う
- キャッシュを適切に利用する
- Static Renderingを活用する
- Bundleサイズを監視する
- Core Web Vitalsを継続的に確認する
という点です。
フレームワークの機能を使うだけではなく、ページごとの役割やユーザー環境に合わせて適切なレンダリング方式を選択することが、高速なWebアプリケーションを作るための基本になります。