- 前回の記事
- 今回の概要
- Pre-rendering とは
- 2種類の Pre-rendering
- Static Generation vs Server-side Rendering
- Static Generation with Data を行う
- Server-side Rendering を行う
- Client-side Rendering を行う
- Server-side Rendering の意義
- 次回
前回の記事
この記事は第3回の記事です。
今までの記事
今回の概要
今回は、Server-side Rendering (SSR) や、 Static Site Generation (SSG) の説明をします。
SSR と SSG はまとめて Pre-rendering と呼ばれます。
引き続き、Next.js のチュートリアルをベースにやっていきます。今回はこのページからやっていきます。
https://nextjs.org/learn/basics/data-fetching/pre-rendering
Pre-rendering とは
Pre-rendering は、 Server-side Rendering みたいなやつの総称です。 SEO のために必要だったりします。
ただ、最近は、Server-side Rendering しなくても、SEO的には問題なし、ということもあるようです。
https://www.ey-office.com/blog_archive/2019/10/15/react-seo-current-status/
https://www.suzukikenichi.com/blog/you-can-use-angular-react-and-vue-for-google-seo/
話は Next.js に戻って、 Next.js だとデフォルトで Pre-rendering ができるようになっています。
Pre-rendering が動いているかどうか確認する方法として、ブラウザで JavaScript を無効にする、という方法があります。サーバーからサーブされるのは、完全な形の HTML なので、 JavaScript が無効になっていても動きます。
ただし、手元でdevモードで試す場合、JSを無効化するとCSSが読み込まれなくなります。それでも、ページは表示できているので、HTMLで送られてきているのはわかります。
2種類の Pre-rendering
Pre-rendering には 2種類あります。
- Static Generation: JSのビルド時にページを生成する方法
- Server-side Rendering: HTTPリクエストが来た時にページを生成する方法
ただし、npm run dev
のような、developmentモードの場合、 Static Generation を使っているページでも、 Server-side Rendering になります。手元で変更した差分を、すぐに反映させるためです。
Static Generation を使うか、 Server-side Rendering を使うかは、ページごとに設定可能です。
Static Generation vs Server-side Rendering
レスポンスが早いため、可能な限り Static Generation を使うのを推奨します。
Static Generation with Data を行う
Static Generatin には2種類あります。
- Static Generation without Data: 外部のデータを必要としない
- Static Generation with Data: APIとか叩いた結果のデータを使って表示する
Static Generation with Data をする場合は、 getStaticProps
関数をを使います。
ページのコンポーネントを export すると同時に getStaticProps
という名前の async
な function を export します。
export default function Home(props) { ... } export async function getStaticProps() { // ここにデータ取得処理とかを書く // props の値がコンポーネントの props に渡される return { props: ... } }
試しに getStaticProps
を使ってみます。
ルートにposts
というディレクトリを作って、そこに pre-rendering.md
と ssg-ssr.md
を作ります。(pages/posts
ではないので注意!!!)
差分は GitHub を見てください: https://github.com/yoshikyoto/nextjs-blog/commit/f374309cb30f69994fd54e7c86a128305ae19c05
markdown ファイルからデータを取得して、 getStaticProps
で渡してみようと思います。
まずは、 index.js で記事一覧を表示します。
必要なデータは
- ファイルの title と date
- ファイル名(ファイル名を記事のIDとする)
ですので、これらを取得して、Reactコンポーネントに渡してやります。
まずは、markdown をパースするためのライブラリ gray-matter
をインストールします。
npm install gray-matter
npm install
をしたら、npm を再起動させるために、docker の再起動をします。
docker-compose down
docker-compose up -d
ファイルからデータを取得するJSを書きます。トップディレクトリに lib
というディレクトリを作成し、posts.js
というファイルを作成します。
コードは長いので、 GitHub の差分を見てください: https://github.com/yoshikyoto/nextjs-blog/commit/f374309cb30f69994fd54e7c86a128305ae19c05
pages/index.js
で、getStaticProps
を追加し、中身は、lib/posts.js
の getSortedPostsData
を呼びます。
import { getSortedPostsData } from '../lib/posts' export async function getStaticProps() { const allPostsData = getSortedPostsData() return { props: { allPostsData } } }
さらに、Home
コンポーネントで引数として受け取るようにし、中身を表示します。実装は GitHub の差分を見てください: https://github.com/yoshikyoto/nextjs-blog/commit/f374309cb30f69994fd54e7c86a128305ae19c05
index ページに記事一覧が表示されるようになったかと思います。
getStaticProps について
今回はファイルからデータを取得しましたが、APIでもよいです。
export async function getSortedPostsData() { const res = await fetch('..') return res.json() }
ちなみに、fetch は Next.js にいい感じに入っているので、import しなくても使えます。
getStaticProps
はサーバーサイドでのみ動作するので、SQLを直接書いても問題ありません。ブラウザから見られるJSには含まれません。
import someDatabaseSDK from 'someDatabaseSDK' const databaseClient = someDatabaseSDK.createClient(...) export async function getSortedPostsData() { // Instead of the file system, // fetch post data from a database return databaseClient.query('SELECT posts...') }
Server-side Rendering を行う
リクエスト時にページを生成する必要があるなら、サーバーサイドレンダリングを使うしかありません。
getStaticProps
の代わりに getServerSideProps
を使うだけです。
今回のサンプルだと Server-side Rendering は不要なので、詳しくは触れません。
Client-side Rendering を行う
Pre-rendering する必要がない場合は Client-side Rendering も使えます。 user-private な SEO の不要なページなどに使います。
SWR(React Hooks)
swr は varcel が作っているReat hookのライブラリです。Client-side Rendering を使うならこれが推奨されています。
import useSWR from 'swr' function Profile() { const { data, error } = useSWR('/api/user', fetch) if (error) return <div>failed to load</div> if (!data) return <div>loading...</div> return <div>hello {data.name}!</div> }
Server-side Rendering の意義
途中でも触れた通り、SEOの観点で言うと、 Client-side Rendering だとしても、Google は正しく解釈してくれるようです。
つまり、SSR の恩恵はほぼ無いでしょう。
第一回で述べた通り、最近の Next.js は、Server-side Rendering よりも、 Statuc Generation に重きを置いています。つまり、 Gatsby.js のような立ち位置になってきています。
さて、次回以降も引き続きこの React チュートリアルはやっていきます。
このチュートリアルが終わったら、僕が Next.js を触って、SSR、SSGなどについて思ったことをまとめたいと思います。
次回
次回はルーティングの話をやっていきます。