React初心者に捧ぐNext.jsのススメ
これはSupershipグループ Advent Calendar 2020の7日目の記事です。
この記事では、フロントエンド開発を始めたばかりの人へ向けて、フレームワークを選ぶ際の参考になれば、と思って書かせていただきました!
(※書き終わって見返すと、半分レンダリングの話してたので、タイトル詐欺かもしれない)
前提
- 対象読者
- フロントエンド開発初学者
- この記事のゴール
- 対象読者がフロントエンド開発をする時に、Next.jsが選択肢の1つとしてあがるようになる
イントロダクション
HTMLファイルとJavascriptだけでwebページを構築していた頃と比べて、昨今のフロントエンド開発は選択肢がたくさん増えています。
それは、偉大なプログラマ達が様々な機能を持ったフレームワーク/ライブラリを生み出してくれたおかげです。
我々はこれらの恩恵にあずかり、複雑なwebページを簡単なコードで実現することができるようになっています。
最近のフロントエンド開発時によく選択肢にあがるフレームワーク/ライブラリは、以下の2つではないでしょうか?
- Vue.js
- React
デザイナーとの協業などを理由に、日本のweb制作ではVue.jsが採用されるケースが多いようです。
実際にGoogle Trendで比較してみると、Vue.jsのトピックの方が若干多いです。
最近はTypescript + Reactの組み合わせもよく聞く気がしますし、トレンドもほぼ同じですね。
※ちなみに、世界トレンドで比較すると、Reactの方が圧倒的に多いです。
というわけで、今回は採用されるケースが少ない?かもしれないReactの、とても便利なフレームワークを紹介します。
この記事で、フロントエンド開発時の選択肢を増えれば幸いです。
Reactとは
ReactはFacebook社が開発しているJavaScriptのライブラリです。
先ほどのトレンドでもある通り、フロントエンド開発においてよく採用されています。
聞いたことはあるけど、何となくしか分からん!という方のために、筆者が初見で?を浮かべた特徴を補足しておきます。(ちょい脱線)
本格的な入門は素晴らしい記事がありますので、そちらをご参考ください!
色々ありますが、筆者は主にこの2つが初めよく分かりませんでした。
- Virtual DOM
- リアクティブプログラミング
Virtual DOM
そもそもDOMとは?
DOMはDocument Object Modelの略で、ブラウザ上のHTMLの要素を操作するインターフェースです。
JavaScriptがHTMLの要素を操作する際、このDOMを通して画面上の要素をJavaScriptのオブジェクトとして扱っています。
Virtual DOMすごい
JavaScriptのDOM操作はレンダリングの負荷が高くなりがちです。
一方で、ReactではまずVirtual DOM(仮想DOM)というReactが管理するDOMを操作し、差分がある箇所だけをHTMLのDOMでレンダリングするので効率的です。
このレンダリングもReactがよしなにやってくれるので早いです。
リアクティブプログラミング
Reactive: 反作用
何かの値が変化すると、それに反応して何かが起こります。
これはフロントエンドの話。なので、値の変化に反応して起こるのは表示の更新です。
リアクティブは値の伝播を中心にした考え方で、元となる値を操作することでそれを利用する表示も自動的に更新されます。
よしなに監視してくれてるんですね。とても便利な仕組みです!
Next.jsのススメ
というわけで、Reactについておさらいした所で、Next.jsの紹介です。
概要
Vercelというホスティングサービスを提供しているVercel社が開発しているReactのフレームワークです。
公式サイトのファーストメッセージ The React Framework for Production をまさしく体現したような、プロダクトの本番環境で使える機能満載 & 設定が容易なフレームワークとなっています。
便利ポイント
筆者が感じた便利ポイントは大きく分けて2つです。
- Pre Rendering
- ルーティングなどのサポート
やはり、一番際立つ便利ポイントはPre Rendering周りではないでしょうか。
というわけで、Next.jsのPre Renderingについて少し解説させてください。
公式のドキュメントでは、こちらのページに解説があります。
Pre Renderingが便利
Pre Renderingとは、読んで字の如く、事前にHTMLをレンダリングすることです。
前提として、Reactによる作成されるWEBページはリクエストされた際に、ほぼ空のHTMLへReactがコンテンツを生成してページを描画しています。
これはブラウザ側でHTMLファイルを組み立てるClient Side Renderingの挙動です。
Googleの検索表示を決める材料を集めているbotは、Reactがコンテンツを生成する前のほぼ空のHTMLファイルを見て、「あ、このページあんま中身ないな」と判断してしまう、なんてことが起きてしまいます。(※最近は改善されつつある)
つまり、対策をしないとSEOに弱くなってしまいます。
また、ブラウザが動いてる端末(スマホやPC)でHTMLファイルを組み立ててレンダリングするので、大きなサイズのJavaScriptを読み込むと遅くなり、しかも読み込むまで何も表示されません。
すごく細かいところでいうと、OGPタグに対応されない、などもあります。
一方でPre Rendering、つまり、事前にHTMLをレンダリングすることで、Googleのbotへコンテンツを正しく認識してもらえたり、スペックの高いサーバでレンダリングしてブラウザへの負荷を下げたりと、Client Side Renderingでの課題を解決できます。
実際に、公式の提供してくれているサンプルを使って、Client Side RenderingとPre Renderingを体験してみましょう。
体験 Client Side Rendering
ブラウザでReactがHTMLファイルをレンダリングするパターンを体験してみましょう。
以下の手順に沿って試してみてください。
1. このページを開いてみてください。
普通に表示されるはずです。
これは、通常のReactで作られたシンプルなサンプルページです。
2. 1のページ上でJavaScriptを無効にしてください(Chromeでの方法はこちら)
3. 1のページをリロードしてください
JavaScriptが無効化されたことで、ほぼ空のHTMLファイルが表示されます。
これは、ReactによってHTMLがレンダリングされていないからです。
つまり、ページへアクセスした瞬間の動作は、以下のようになっています。
- 空っぽのHTMLファイルが読み込まれる
- JavaScriptが読み込まれる(※さっきは、ここを無効化した)
- Reactのコンポーネントが初期化され、レンダリングする
体験 Pre Rendering
では、続いてPre Renderingの挙動確認です。
1. このページにアクセスしてみてください
2. 1のページ上でJavaScriptを無効にしてください(Chromeでの方法はこちら)
3. 1のページをリロードしてください
どうでしょう? JavaScriptを無効化した状態でも、変わりなくコンテンツが表示されていませんか?
これは、Pre Renderingによって事前にHTMLファイルとJavaScriptが生成されているからです。
つまり、ページへアクセスした瞬間の動作は、以下のようになっています。
- 事前にレンダリングされたHTMLファイルが読み込まれる
- JavaScriptが読み込まれる(※さっきは、ここを無効化した)
- Reactのコンポーネントが初期化され、Linkコンポーネントなどのインタラクティブなコンポーネントが読み込まれる
※このデモページ、js無効にしてもLink効くのは何でだろう??
2種類のPre Rendering
Next.jsの提供するPre Renderingは以下の2種類があります。
- Server-Side Rendering
- Static Generation
この2種類の違いは、いつレンダリングしているか?です。
Server-Side Rendering
Server-Side Renderingは、ユーザーがアクセスした時、サーバ側でHTMLをレンダリングします。
アクセスの度にサーバでレンダリングをする都合で、Static Generationより表示するのに時間がかかります。
が、上述したようなClient Side Renderingの課題は克服することができます。
Next.jsではデフォルトでServer-Side Renderingが適用されるようになっています。(設定で無効にすることは可能です)
Static Generation
Static Generationは、ビルドしたタイミングでHTMLをレンダリングします。
なので、ユーザーがアクセスした時には常にレンダリングされたHTMLファイルを表示してくれます。
よって、ページの表示速度はClient Side Rendering、Server Side Renderingよりも高速です。また、botがアクセスした時にはHTMLファイルが完璧に揃っているため、SEO的に不利になりません。
しかし、ビルド時にHTMLファイルを生成しているわけですから、外部データなどで表示を更新する場合は再度ビルドし直す必要があります。
そのため、一般的なWEBサービスはClient Side RenderingかServer Side Renderingが採用されるでしょう。
外部データの更新頻度が少ないランディングページや、問い合わせページはStatic Generationがぴったりかと思います!
ブログもよくこちらで作成されます。
どのレンダリングを採用すべきか?
Next.jsでは、要件的に問題なければStatic Generationを採用することが推奨されています。
どのレンダリングを採用するかは作るサービスやページに応じて適切に判断しましょう。
簡単にテーブルにまとめておきました。
Client Side Rendering | Server Side Rendering | Static Generation | |
---|---|---|---|
DOMマウント(HTMLの生成) | ページアクセス時 | ページアクセス時 | ビルド時 |
メリット | ・ページ遷移が基本早い | ・JS読み込む前にHTML表示できる | ・一番表示速度が早い ・SEO不利なし |
デメリット | ・SEO不利(最近、クローラーが優秀で改善傾向にあり) ・JSのファイル大きいと読み込み遅い(端末依存もありそう) ・OGPタグ非対応 |
・webサーバ必要 ・windowなど、ブラウザ側にしか存在しないグローバルオブジェクトにアクセスできない |
・頻繁に更新される外部データを表示に使う場合はビルドし直し必要なので向いてない |
相性良さそう | 認証ありのWEBサービス(SEO不要なため)など | SEO必要な動的ページ、SNSなど | LP、ブログ、QAページなど |
※zennのテーブル、改行効かない?ので↓に読みやすい画像も貼っておきます。
Next.jsは簡単にページ単位でPre Renderingを変えられます!
ページに応じて最適な方式を選べるのは素晴らしいですね。
また、標準がServer-Side Renderingになっており、手軽に導入できるのが本当に有難いです!
ルーティングなどのサポートが便利
Next.jsで便利だなーと感じたポイントは、標準SSR以外にもあります!
Reactで通常アプリケーションを構築する際は、create-react-appというツールを使って作成します。
しかし、ルーティングを追加するにはreact-routerを、メタタグを付与するにはreact-helmetを、と色々な関連ライブラリを追加・設定する必要があります。
Next.jsはそういったライブラリが提供する機能を標準装備してくれている上、圧倒的に使いやすくなっています。
この便利さは、チュートリアルを実際にいくつか進めて実感していただくのが良さそうです!(1記事にするには長すぎたのもあります...)
例えば、ルーティング定義は、こちらですね。
Vueを書いていて、Nuxt.jsの経験がある方だとこれまで話したお話は知ってるぜ!ってものが多かったかもしれません。
ReactでNuxt.jsのような強力なフレームワークのサポートを受けたいのであれば、Next.jsを選択しておけば間違いないかと思います!
非常に便利なフレームワークなので、ぜひ公式ドキュメントをのぞいてみてください!
最後に
ここまでお読みくださり、ありがとうございました!
筆者はサーバサイドをメインに書いていますが、フロントエンドも本当に楽しいですよね!
自分で画面を作っていくのは気持ちいい!
業務上、VueもReactも書いたことがありますが、どちらも勉強になることが多くて楽しかったです!
フレームワークの設計は、本当に綺麗で素晴らしい...!
公式ドキュメントをまとめただけのような記事ですが、少しでもお役に立てれば嬉しいです。
最後に今所属しているチームのPRを貼っておきますので、もしご興味あればのぞいてみてください!
PR
【Supership】ではプロダクト開発やサービス開発に関わる人を絶賛募集しております。
ご興味がある方は以下リンクよりご確認ください。
【Supership株式会社 採用サイト】
是非ともよろしくお願いします。
Appendix
引用・参考記事
Discussion