まえがき
今回タイトルにしたSSRというのは、Server Side Renderingのイニシャルで、広義にはテンプレートエンジンを用いてサーバーサイドでHTMLを生成する手法も含まれるとは思いますが、以下説明しているSSRはクライアントで組み立てていたVirtualDOMをサーバーサイドで組み立てるアプローチのことを指すという認識でお願いします。
まずSSRは一体何を解決するためにあるのか、そこから考えていこうと思います。
SSRまでの経緯
だいぶ省略しますがページを表示するまでのパターンを考えます。
もっともシンプルなのは、HTMLファイルを直接返すアプローチです。
サーバーはHTMLファイルを返すだけだし、クライアントはHTMLをパースしたら表示するだけです。
CSSを使えばインタラクティブに見せることもできます。テンプレートエンジンやタスクマネージャーなどを使えば、共通化したりもできます。
しかし次第に動的にサーバー通信を行って、その結果をユーザーに見せたり、入力を受け付けるようなページを作りたくなってきます。そしてJavascriptを用いて、ユーザーの入力やデータの更新などに反応してDOM構造を操作したりするようになってきました。
最初はJQueryなどでうまくまわっていましたが、例えばインタラクションが複雑になるにつれてDOMの操作に時間がかかるようになりVirtualDOMを描画するReactのようなライブラリが出てきたり、データが複雑になるにつれて、MVCの分離が提唱されFluxやReduxのようなフレームワークがでてきました。しかし、それにあわせてJavascriptファイルの重さがかなりのものになってきました。
このようなCSR(Client Side Rendering)の場合、Javascriptファイルを読み込み、実行するまでの時間ユーザーは待たされることになります。
一般に、ネットワークIOよりも、ディスクIO、CPU時間の方が圧倒的に速いので、サーバー側で、ユーザーに描画するDOMを組み立てて返した方が速い、これが、SSRが出てきた経緯だと考えます。
メリット・デメリット
たぶんこの記事は見る人によってかなり多様なケースがありえると思うので、おそらくどんなケースにも当てはまりそうなことだけ書こうと思います。
SSRは主にはFMP(First Meaningful Paint)のスコアを上げるためのアプローチだと考えられます。
なので、SEO対策をする必要があるサービス(ブログなど)や高速化にリソースを割けるときには有効なアプローチです。
ちなみにSEO対策、というのもいろんなものがあるのですが、上で言っているのはモバイル検索順位に表示速度も影響することに関してです。
GoogleのクローラーはJavascriptを解釈できるようになっているので、Javascriptを読み込まないと表示されないコンテンツを指してのSEO対策はSSRをしようがしまいが条件は変わらないためメリットとはいえません。
逆に言えば、そこに対してメリットがないサービスにSSRを使おうとしている場合、サービスが複雑になる以上にリターンが少ないケースが多いと思います。おそらくこれは大きなデメリットだと思います。
SSRにしたからといって、ユーザーの入力などに反応するにはクライアント側でJavascriptでハンドリングしないといけないですし、URLをまたいでも1つのアプリのように見せるSPAの場合、どのページにどのように移動してもクライアント側の状態とサーバー側の状態が必ず一致するようにAPIを設計しないといけないですし、常に気をつけなければいけません。これはかなり苦労すると思います。
さいごに
実は今next.jsを触っていて、それに関する記事を書こうと思っていたのですが、触っている中で自由度が低く複雑なわりに解決できることが少ないなと思い始めたので、SSRとは何か、何のためのものか、本当に必要なのかと考えをまとめるためにこちらの記事を先に書きました。誤りなどあればコメントお願いします。
追記(2020/02/26)
Next.jsに関しては現在かなり洗練されてきているように感じていて、Next.jsのために覚えなければならないことは少なからずあるもののそこまで多くなく、(単語にするとpagesディレクトリ、publicディレクトリ、getInitialPropsくらい)多様な利用方法にも対応できるような設計になっているので、react + webpack-dev-serverとかで開発を始めようと思っているくらいのノリなら迷わずNext.jsを使って見ることをおすすめします。
みなさんの思考の手助けになると幸いです。
追記(2020/05/24)
Next.jsで開発中のブログサービス(Minimal Blog)も参考にしてみてください。