まとめ サーバーサイドレンダリングについて、改めて勉強し直してみる
去年からずっと調べてきたサーバーサイドレンダリング(以下 ssr)ですが、ようやく大体理解できてきたので一旦まとめようと思います。
ssr とは
JavaScript(以下 JS)がサーバー側で実行され DOM がレンダリングされた後、残りをクライアント側に投げる手法。
逆にクライアントサイドレンダリング(以下 csr)とは、まずクライアント側に全て投げた後、JS がクライアント側で実行されて DOM がレンダリングされる手法。
ssr のメリット
- 多くのケースでファーストビューが素早く描画される
- Twitter や Facebook など JS にクローラが対応していないサイトに対し、ダイナミックルーティングでも seo が反映可能である
多くのケースでファーストビューが素早く描画される
一般的に最もよく挙げられるメリットですね、実際早いみたいです。
なぜ早いかというと、
- ssr はほとんどのケースでプリレンダリングが行われているため
- useEffect で api を叩く csr と異なり、まず api を叩いて結果を取得し、その結果を props に流し込んでファーストレンダリングが可能なため
- クライアント側で使用されているスマホや PC よりサーバー側の PC のほうがスペックが高いため
あたりかなーと、ちなみに 1 の理由は ssr とは直接的な関係はないです。
Twitter や Facebook など JS にクローラが対応していないサイトに対し、ダイナミックルーティングでも seo が反映可能である
そもそも、ダイナミックルーティング(動的なルーティング)とはなんぞやと言う方もおられると思いますが。
イメージとしてはニコニコ動画やクックパッドを思い浮かべて頂けるとわかりやすいと思います。
ニコニコ動画やクックパッドの各動画ページ、レシピページは毎回毎回手作業で html ファイルを作っているわけではないです。
元となるテンプレート用の html ファイル(正しい表現かどうか怪しい)があって、url のパラメータに合わせて描画が行われている感じです。
Google のクローラはむちゃくちゃ優秀なので、csr で spa みたいなケースであっても、各ページの seo をきちんと反映してくれるみたいです。
ところが Twitter や Facebook の場合はそうはいかず、csr で spa みたいな状態では、各ページの seo は全てトップページの seo が反映されてしまいます。
csr の場合react-snapのようなパッケージを導入し、プリレンダリングを行うことにより静的なルーティングにおける seo は対応が可能です。
ただ csr の場合、プリレンダリングを行ったとしてもダイナミックルーティングにおける seo の対応はできません、これが JS に対応していないクローラの限界ですね。
そのため、ダイナミックルーティングでかつ Twitter や Facebook のようなサイトで seo を反映したい場合は、必然的に ssr の選択肢を取るしかないと思われます。
ssr のデメリット
- アクセスが増えるごとにファーストビューの描画速度が落ちていく
- csr と比べやはり開発は難しい
- document など取得できない値や使用できないツールが存在する
アクセスが増えるごとにファーストビューの描画速度が落ちていく
言わずもがなですが、サーバーへのアクセスが集中してしまうと JS の実行速度や api 周りの速度が落ちてしまいます。
そのため、ファーストビューがなかなか描画されず、結果的に描画が遅くなるケースもあるみたいです。
事実、過去とあるレシピ系サイトのエンジニアの方のお話で、サイトに訪れる人が増えるごとに速度が落ちていて困っているというお話を伺ったことがあります。
その場合はサーバーの増強を行うしか手段がないため、結構お金がかかる印象があります。
csr と比べやはり開発は難しい
Redux 周りの開発難易度はやはり少し高い印象を受けます。
サーバ側とクライアント側で同じ状態を保つ必要があるため、中途半端な知識では全く太刀打ちできません。
document など取得できない値や使用できないツールが存在する
意外と見落としがちですが、サーバ側でレンダリングを行う以上、クライアント側でのみ提供されている値やツールは使用できません。
例えば document 変数などは使えず、ブラウザの画面サイズなんて取得できるわけがありません。
そのため、ブラウザの画面サイズを利用するような JS を組む場合は、useEffect などで取得した後に state に格納する、みたいなロジックを組まないといけません。
で、これをやると csr よりも描画が遅くなることも多いのでは?とも思うのですが、どうなんですかね。
またサーバー側ではローカルストレージなども使用できません、当たり前ですね。
なのでredux-persistなどを使う場合はどういった挙動を行わせる必要があるのか、ちょっと調べきれていないです申し訳ない。
結果的に開発難易度の話にも繋がりますが、ssr を導入したことによる不便なことも多い印象です。
ssr を導入したほうが良いケース
- Twitter や Facebook など JS にクローラが対応していないサイトに対し、ダイナミックルーティングでも seo が反映したい場合
個人的にはこの理由しか挙がりません。
なので、動画サイトやレシピサイトは必然的に ssr が必須となるわけですね。
逆に、他のケースでは不要なんじゃないの?と思っています。
ファーストビューに関しては、コードスプリッティングを行ったり、react-snap を導入したりと、csr でもある程度対応方法はあります。
よく ssr 不要論で言われていますが、ssr を導入するとあくまでファーストビューが多少早くなるだけです。
ssr を導入する前に、できるかぎりのチューニングは行いましたか?と。
また、サーバーへの負荷が高まったケースに対する認識が甘い状態で安易に ssr を導入している現場も散見されますが、本当にそれで良いのかなぁと。
ssr を用いた開発は、やはり難易度はぼちぼち高いと思います、慣れちゃえば大丈夫なんでしょうけどね。
特に csr を理解しないまま ssr の理解を深めるのは危ないと思います、サーバーへのアクセスが集中してお金が無駄にかかっちゃったりすると目も当てられません。
間違ってる箇所やまだ知識が足りていない部分もあるかもしれないです、申し訳ないです。