Next.js vs React レンダリングスピード対決
背景
私は最近よく、Next.jsを使用します。しかし、React+Viteを使用する人もよく見かけます。そこで双方のメリット/デメリットを調査していると、SSR(Server Side Rendering)とCSR(Client Side Rendering)に違いがあるとわかりました。これは初期レンダリングに影響します。
この影響を感覚的なものではなく、数値で理論的なものにしていきましょう。
環境
- Next.js (App Router, TypeScript)
- Vite (React/TypeScript)
- Google Chrome
プロジェクトの作成については、以下の記事を参考にしてください。
アプリケーションの実行まで完了して、次に進んでください。
今回使用するページをできるだけ同じ記述量にするために、それぞれ以下のように書き換えます。
Next.js
export default function Home() {
return (
<div>
<h1>Hello Next.js!</h1>
</div>
);
}
React + Vite
export default function App() {
return (
<div>
<h1>Hello React+Vite!</h1>
</div>
);
}
Lighthouseの使用方法
chromeのWebページの品質監査を自動化ツールLighthouseを使用してレンダリングスピードを測ります。
まず、先ほど実行したchromeでF12を押してデベロッパーツールを起動して、上のバーからLighthouseを選択します。
各種項目については、以下のように選択してください。
- モード:ナビゲーション(デフォルト)
- デバイス:デスクトップ
- カテゴリ:全て選択

選択したら「ページ読み込みを分析」を押してください。監査が開始されます。
以下のようにスコアが表示されたら、監査完了です。
左がNext.js、右がReact + Viteになります。

スコアを見ると、パフォーマンスとSEOに少し差があります。
今回は、パフォーマンスの一部について見ていきます。
【検証】 レンダリングスピード測定
Lighthouseを少しスクロールすると以下の指標が表示されています。

| FCP | LCP | TBT | CLS | SI | |
|---|---|---|---|---|---|
| Next.js | 0.2s | 0.3s | 0ms | 0 | 0.2s |
| React | 0.9s | 1.5s | 0ms | 0 | 0.9s |
このようにFCPとLCPに大きな差が出ています。
【追加検証】 画像のレンダリングスピード
画像の表示にどれくらいの時間がかるか検証します。
今回は比較のため、10MBのpng画像を以下のサイトからダウンロードして使用します。
ダウンロードしたら、それぞれのプロジェクトのpublicディレクトリに入れてください。
次に、以下のように書き換えて、画像を表示させます。
Next.js
export default function Home() {
return (
<div>
<h1>Hello Next.js!</h1>
+ <img src="/10MB.png" alt="" />
</div>
);
}
React + Vite
export default function App() {
return (
<div>
<h1>Hello React+Vite!</h1>
+ <img src="/10MB.png" alt="" />
</div>
);
}
先ほどと同様にLighthouseで監査を実行します。

LCPを見ると、どちらも9秒以上かかっているのがわかります。
しかし、Next.jsには<Image>コンポーネントが存在し、これは簡単にいうと、画像を最適化してくれます。
この<Image>をNext.jsで使用します。
+ import Image from "next/image";
export default function Home() {
return (
<div>
<h1>Hello Next.js!</h1>
- <img src="/10MB.png" alt="" />
+ <Image src="/10MB.png" alt="" width={640} height={640} />
</div>
);
}
Lighthouseで監査を実行してみましょう。

LCPは1.2秒となり、<Image>を使用しなかったときに比べて、大幅に速くなっています。
【考察】 なぜ、Next.jsのFCPやLCPが速いのか?
Next.js(App Router)の場合、SSR(Server Side Rendering)を採用しているため、サーバー側ですでにHTMLが生成された状態でブラウザに届きます。そのため、HTMLを受け取った瞬間に表示できます。
一方、React + Viteは、CSR(Client Side Rendering)であるため、以下の順でレンダリングが行われます。
- 空のHTMLとJavaScriptファイルがブラウザに届く
- JavaScriptを実行する
- DOMを生成して、描画する
このため、FCPやLCPがNext.js(App Router)に比べて遅くなります。
【まとめ】 結局どっちを使うべき?
今回の検証では、Next.js(App Router)が初期レンダリングにおいて、優位であることがわかりました。
これは、ユーザーがWebページを訪れた瞬間にコンテンツを表示させたい場合(例えば、LPやブログ)に向いています。
しかし、初期表示速度を重視せず、シンプルな構成で開発体験を優先するなら、React + Viteを選ぶべきです。
Discussion