1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Next.js 一強の時代は終わったのか?

1
Posted at

少し前まで、ReactベースでWebアプリを作るなら
「とりあえずNext.js」という空気がありました。

しかし最近は、

  • バンドルが重くなりがち

  • 抽象化が多くて内部が見えにくい

  • もっと軽量な選択肢があるのでは?

といった声も増えています。

実際、Vercel が開発する Next.js 以外にも、
AstroSvelteKitQwik などが実運用レベルで普及し、
選択肢は明確に広がりました。

とはいえ、「批判されている=劣っている」という話ではありません。
重要なのは、思想の違いがどのようなコードと配信物(HTML/JS)の違いを生むのかです。

現在の大きな潮流は、

  • Hydration を減らす(あるいは回避する)

  • 配信する JS を必要箇所に限定する

  • サーバー実行を増やす

という Ship less JavaScript の方向に集約されつつあります。

今回は、以下4つのフレームワークの設計思想を比較します。

  • Next.js
  • Astro
  • SvelteKit
  • Qwik

コード比較する機能

まずは最も単純な例として「カウンター」を実装します。

仕様

  • 初期値 0

  • ボタンを押すと +1

このシンプルな機能でも、各フレームワークの思想が見えてきました。

1. Next.js(Server Components + Client Components)

Next.js の App Router では Server Components がデフォルトです。
インタラクティブな部分だけを Client Component に分離します。

app/counter/page.tsx
// Server Component
import CounterClient from "./CounterClient";

export default function Page() {
  return (
    <div>
      <h1>Counter</h1>
      <CounterClient />
    </div>
  );
}
app/counter/CounterClient.tsx
// Client Component 
"use client";

import { useState } from "react";

export default function CounterClient() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>{count}</p>
      <button onClick={() => setCount((c) => c + 1)}>
        Increment
      </button>
    </div>
  );
}

特徴

  • Reactベース

  • "use client" を付けたコンポーネントのみがクライアントJSになる

  • それ以外はサーバーでHTML生成

思想

Next.js は
「サーバー中心にし、必要な部分だけをクライアント化する」
という方向へ進化しています。

2. Astro(Islands Architecture)

Astro は HTMLを基本とし、
インタラクティブな部分だけを「アイランド」として読み込みます。

src/pages/counter.astro
---
import Counter from "../components/Counter.tsx";
---

<Counter client:load />

src/components/Counter.tsx
import { useState } from "react";

export default function Counter() {
  const [count, setCount] = useState(0);

  return (
    <>
      <p>{count}</p>
      <button onClick={() => setCount((c) => c + 1)}>
        Increment
      </button>
    </>
  );
}

特徴

  • デフォルトはHTMLのみ

  • client:* を付けた部分だけJS化

  • 読み込みタイミングも制御可能

思想

HTMLを出し、JSは必要な分だけ後から足す という考え方。

3. SvelteKit

SvelteKit は SSR → hydration がデフォルトです。

src/routes/+page.svelte
<script>
  let count = 0;
</script>

<p>{count}</p>
<button on:click={() => count += 1}>
  Increment
</button>

特徴

  • 状態管理が非常にシンプル

  • コンパイル時に最適化

  • csr=false でクライアントJSを無効化可能

思想

SSRを前提にしつつ、軽量なJSを生成する という考え方。

4. Qwik

Qwik は hydrateせずに resume する設計です。

counter.tsx
import { component$, useSignal } from "@builder.io/qwik";

export default component$(() => {
  const count = useSignal(0);

  return (
    <div>
      <p>{count.value}</p>
      <button onClick$={() => count.value++}>
        Increment
      </button>
    </div>
  );
});

特徴

  • useSignal による細粒度状態管理

  • $ 境界は遅延ロード可能

  • 実装コードは必要になるまで読み込まれない

思想

Resumability(再開可能性)
= ページの状態をそのまま復元する という考え方。

実装から見える思想の違い

フレームワーク デフォルトの前提 インタラクティブ化単位
Next.js Server Components "use client" 境界
Astro HTML + Islands client:* 指定
SvelteKit SSR → hydration ページ / コンポーネント
Qwik Resume $ 境界

実務的な選定指針

コンテンツ中心サイト

→ Astro

SSR前提で軽量なUI

→ SvelteKit

極限まで初期JSを削りたい

→ Qwik

エコシステム重視・企業開発

→ Next.js

結論

Next.js 一強の時代は、終わったというより「多様化した」 と言えます。

重要なのは、
「どれが最強か」ではなく、
「どれが要件に合うか」

フレームワークは目的ではなく手段。
コードの違いは、思想の違いです。

参考

採用拡大中!

アシストエンジニアリングでは一緒に働くフロントエンド、バックエンドのエンジニアを募集しています!

少しでも興味ある方は、カジュアル面談からでもぜひお気軽にお話ししましょう!

お問い合わせはこちらから↓
https://official.assisteng.co.jp/contact/

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?