React.jsとNext.jsの違い アドベントカレンダー1日目

## はじめに
アドベントカレンダー1日目
今日は`React.js`と`Next.js`の違いについての記事となります。
**そんなものいくらでも見たわ！** って方、
僕もそう思います。

コンセプトとしてはできるだけ初心者に寄り添ったものにしようかなぁと思います。

## 前提
ReactとNextの違いを説明する前に前提としてSPAとMPA SSRとCSR,SSGの説明をしておく必要があります。
### SPAって何？？
SPAとは**Single Page Application**のことです
じゃあSingle Page Applicationってなんやって話になるんですけど、
文字通りページが一個しかないアプリケーションのことです。
これは対義語である**MPA(Multi Page Application)**と比較しながら説明したほうがわかりやすいです。

まずユーザーがページにアクセスした際に(DNSなどのもろもろは端折りますが)そのwebアプリケーションに使われているすべてのページの情報を一度に全て取得してくるのがSPAです。
そのため一番最初のアクセスには時間がかかりますがページ遷移などの時間が短いことが特徴です。

それに対しページごとにそのページに必要な情報を取得してくるのがMPAです。
どのページに行ってもそのページに必要な時間だけがかかります。

SPAの例としては[Github](https://github.com)や[X(旧Twitter)](https://twitter.com)などが挙げられます。
MPAの例としては[Amazon](https://www.amazon.com)などでしょうか
従来のwebサイトはMPAであることがほとんどです。


### SSR CSR SSGって何？？
次に**SSR** **CSR** **SSG**についてのお話です
これらはそれぞれ
**Server Side Rendering**
**Client Side Rendering**
**Static Site Generator**
の略語です。
ではそれぞれどのように違うのか

#### SSR
サーバーサイドでレンダリングし生成されたhtmlと一部javascriptをクライアントに返した後クライアントサイドのブラウザで一部javascriptの実行を行う。
ある程度のレンダリングがサーバー側で行われるためクライアントのデバイスの性能による影響を受けづらい。
<details><summary>レンダリングとは</summary>
javascriptによって記述されたコンポーネントや要素をブラウザが解釈できるようにhtmlに変換すること。
</details>

#### CSR 
サーバーからクライアントにjavascriptを返し、クライアントサイドのブラウザでレンダリングを行う
レンダリングをすべてクライアントサイドで行うため、サーバー側の負荷が少ない。

#### SSG
ビルド時にHTMLを生成して、クライアントからリクエストがあるとあらかじめ生成されていたHTMLを返す。
ブログやヘルプページなどユーザーがそのサイトに介入しないものに使われる。
クライアント、サーバーともにパフォーマンスが良いが用途に制限がかかる。

#### ※PPR
これはまだexperimental(実験的)ですがPartial Pre Renderingというあとでお話しするNext.jsで採用されているレンダリング方法があります。
これに関しては私もまだわからないことが多いですがおおよそISRとSSRを組み合わせたものだと思われます

## React.jsとは
本題に入ります
現在フロントエンド界隈では人気なReact.js
一体どういったものなんでしょうか。

まず開発元
Reactは**Facebook**が開発を行っています。
Facebookを作っている会社ですね。
GAFAのFの部分です。

次に開発期間
reactのリポジトリの[first release](https://github.com/facebook/react/releases/tag/v0.3.0)を見ると
**2013年6月3日**にリリースされていることがわかります
つまり執筆時点で約10年の歴史があるということです。

で、じゃあreactとはなんじゃということですが
reactはjavascriptの**UIライブラリ**です。
UIライブラリとはUI(user interface:ユーザーとシステムを繋ぐ部分　ここでいうブラウザの画面)を構築するライブラリです。
react単体ではSPAとして動作をします。
パフォーマンスや可読性がとてもよく書いていて楽しいライブラリです(主観)
ですが他のフレームワークに比べ**学習コストが高い**ということが一般的に言われています。


## Next.jsとは
こちらのReact同様にフロントエンド界隈で人気なNext.js

開発元
Next.jsは**Vercel**が開発を行っています。
Vercelはwebホスティングサービス **vercel**を経営しています。

<details><summary>webホスティングサービスとは</summary>
**webホスティングサービス**とはWebサイトをインターネット上にアクセス可能にするためのサービスです。

本来webサイトとはグローバルIP、ドメインを取得し、サーバーをグローバルIP上に設置し、ドメインとグローバルIPをDNSに登録することでやっと公開することができます。
それらをサービスとして提供しているのがwebホスティングサービスです。
これらを利用することでドメインの取得も、グローバルIPの取得もサーバーの用意も要らずにwebサイトとして後悔することができます。

言ってしまえば出版社みたいなものです。自分が書いた本はそのままでは自分しか読めませんが出版社に出すと色々な人に見てもらえますよね。
</details>

次に開発期間
Nextのリポジトリの[first release](https://github.com/vercel/next.js/releases/tag/1.0.1)を見ると
**2016年10月28日**にリリースされていることがわかります。
執筆時点で開発期間は7年ほど。
reactに比べると3年ほど短い歴史です。

で、じゃあNext.jsとはなんじゃということですが
Next.jsはreactを内包したwebフレームワークです。
<details><summary>webフレームワークとは</summary>
webフレームワークとはwebアプリケーションを作成するために必要とされる機能が提供されたパッケージ
</details>

現在Next.js バージョン14ではSSRとCSRの両方を採用しています。
サーバーサイドでレンダリングできるものはサーバーサイドで行い、クライアントでしかレンダリングできないものはクライアントサイドで行います
全てをサーバーサイドでレンダリングするわけではないのでサーバースペックが抑えられ、かつ全てをクライアントサイドでレンダリングするわけではないのでクライアントの負担を減らすことができます


## 何が違うのか
では、何が違うのか。
何が違うと言われると、困るんですけどReactでできてNextにできないことはほとんどありません。
ではNextはReactに比べ何ができるのか。
私が第一に思いつくのは`ファイルシステムベースルーティング`でしょうか
Nextはデフォルトで`ファイルシステムベースルーティング`を採用しています

<details><summary>ファイルシステムベースルーティングとは</summary>
アプリケーションのルーティングをディレクトリとファイルを用いて行うことです。

例えば
`app/hoge/page.tsx`というファイルを作成するとそのファイルは`https://example.com/hoge`
にアクセスした際に返す要素となります。
こうすることで直感的にファイルとページを紐づけることができます
</details>

Reactのルーティングは開発者がコードとして定義する必要があり、これが個人的には割とめんどくさいです。

他にはNext独自の関数や、コンポーネントが挙げられます。
その中で例を挙げるとNextには`Image`コンポーネントが実装されています。
Imageコンポーネントはhtmlの`img`要素に当たるコンポーネントです。

このコンポーネントは`width` `height`を指定しなければ警告が出されます。
img要素はwidth heightを指定しなくても特に警告も出されません。
(Nextではそもそもimgを使うと警告が出ます)

<details><summary>なぜwidthとheightを指定させるのか</summary>
それはおそらくCLSを起こさないため、パフォーマンスを上げるためだと考えられます

<details><summary>CLSとは</summary>
Cumulative Layout Shiftを略した言葉です。
webサイトにアクセスした時最初は文字列が見えますが画像の読み込みには少し時間がかかりますよね。

その時画像の大きさ分だけ画面の領域を確保しておかないと画像が読み込まれた時にレイアウトが崩れます。
このようなことをレイアウトシフト(画像だけではない、サイトアクセスから完全に読み込まれるまでの間でレイアウトが崩れること)と言います
</details>
パフォーマンス向上に関して
画像の要素が小さいのに4Kの画像などを貼ると実際に見えないような小さいところまで高画質になりデータ量が増えます。
そのようなことを防ぐためにNextでは画像のの最適化が行われています

参照:https://nextjs.org/docs/pages/api-reference/components/image#loader
</details>

逆にNextだと面倒臭いことも実はあったりします
webアプリを`vercel`以外にデプロイすることを考えた場合です。

ReactはSPAであるため静的ファイルだけを配信すればいいです。
それに対しNextはSSRをサポートしているという点からサーバーサイドのレンダリングを行うサーバーが必要です。(SSGで使う場合は必要ない)

以前awsがコンセプトのハッカソンがあったのですがそこでvercelを使わない場合などを考えさせられましたが色々悩んだ記憶があります。

候補として上がったのが`AWS amplify`を使う方法と`S3`と`lambda`を使う方法でした。
いずれも間に合わずにvercelにデプロイしたのがいい思い出です(近いうちにリベンジします)

vercelだとボタンぽちぽちで終わりますが自分でインフラ構築するとなるとかなりめんどくさい感じはあります。

それ以外だとバージョン更新がめちゃくちゃ早いことですかね。
キャッチアップが大変です。(新しいものが増えて私は楽しいですが)

## 最後に
今回はReactとNextの違いを書きました。
色々話が長くなってしまいましたが私の意見としては基本的にはNextでいいんじゃないかなぁと思ってます。

ですが企業とかだとvercelと一緒に心中できるならNextでもいいという制約もあるとかないとか

私自身はNextのファイルシステムベースルーティングが好きで使ってます。
Reactでもファイルシステムベースルーティングができるようにするライブラリがあるとかないとかを風の噂で聞いたので使ってみたいですね