サーバサイドレンダリングについて

vueやnuxtを触り始めたものはいいものの、サーバサイドレンダリングの良さと言うか概念が
ほんのりとしかわからなかったので、他の用語とかも含めて調べてまとめてみる

# 基本用語の確認
### レンダリング
HTMLとCSSを解析してコンテンツを画面に表示すること。

### DOM (Document Object Model)
HTMLなどのドキュメントの構造をメモリ内に表現することで、ウェブページとスクリプトやプログラミング言語を接続するもの(プログラミングインターフェース、API的なもの)。

DOMはドキュメントをオブジェクト(マークアップによって区切られたまとまり)の木構造モデルで表現することで、
ドキュメントを各種プログラミング言語から操作・利用できるようにする[^5]。
(ドキュメントの種類や操作をするプログラミング言語には依存しない)
このプログラムから操作・利用されるオブジェクトは総称して`Node`と呼ばれる[^6]

各ブラウザは[標準仕様](https://triple-underscore.github.io/DOM4-ja.html)にもとづいてDOMを独自実装している。
ブラウザ内のレンダリングエンジンはDOM(およびCSSOM)に基づいてレンダリングを実行する。
詳しくは以下参照 (あとで読む)。
- [レンダリング ツリーの構築、レイアウト、ペイント  \|  Web  |  Google Developers](https://developers.google.com/web/fundamentals/performance/critical-rendering-path/render-tree-construction?hl=ja)
- [ブラウザレンダリング入門〜知ることで見える世界〜 - Qiita](https://qiita.com/codemafia0000/items/caed57ec30d638e40728#%E5%8F%82%E8%80%83)

### 仮想DOM
DOMと1対1に対応にある単純なJavaScriptのオブジェクト(木構造)とそれを用いたdiff・patchアルゴリズム、
あるいはその実装のこと[^7]。

- diff (差分検知)
仮想DOMのノードが変更あった場合、変更前後の仮想DOMを比較して変更箇所を特定する。

- patch
仮想DOMで変更があった箇所だけDOMに反映する
断続的にDOMを変更するのではなく、特定のタイミングでバッチ処理的に反映を行うらしい。
詳しくは[ここ (あとで読む)](https://saneyukis.hatenablog.com/entry/2014/09/03/134858)

#### DOMの直接の操作と比べた場合のメリット
DOMの直接の操作の場合はどの要素を参照してどの要素を変更するのかをJS側で把握する必要があったが、
仮想DOMを使うことでその必要がなくなるので、

- UIとロジックを分離できる
- 複雑なロジックの実装がしやすくなる
- 設計やテストがしやすくなる
- viewのコンポーネント化
 
# クライアントサイドレンダリング 
JavaScriptを使用したDOM操作することで部分的に画面変更を適用することで、直接ブラウザでページをレンダリングすること。
データ取得やテンプレーティング、ルーティングはサーバ上ではなくクライアント上で行われる。
サーバとはデータ(json)のみを通信し、そのデータに基づいてコンテンツ内容の変更やページ更新を行う。

#### 従来のレンダリング方法(静的/動的コンテンツ)と比べた場合のメリット
従来の画面の変更に伴って1つのhtmlを再構築するレンダリング方法と比べて、

- 画面全体をレンダリングし直す必要がないため、ページの操作性を向上できる
- 部分的なレンダリングを行うことで、高度なUIを実現できる。

SPAのような快適な操作性が求められるページの実装に向いている。


# サーバサイドレンダリング
狭義の意味
> クライアントサイドおよびサーバサイドの両方のHTMLレンダリングの仕組みを、
> 共通のロジックを用いて動作させること[^1]。

サーバサイドJS実行環境と仮想DOMに基づいたフレームワークの利用して、サーバサイドで仮想DOMの差分検知とその通知を行って、クライアントサイドで部分的なDOM操作を行うこでHTMLレンダリングを行うこと。

アイソモーフィックJavaScriptとユニバーサルJavaScriptとはほぼ同じ意味。

#### クライアントサイドレンダリングと比べた場合のメリット
- SEO対策
サーバサイドでレンダリングすることで、クローラが完全に描画されたページを直接参照ができる

- パフォーマンスの改善 
クライアントサイドはJavaScirptのダウンロードを待たなくてよくなり初期の画面レンダリング時間が短縮できる([詳細](https://developers.google.com/web/updates/2019/02/rendering-on-the-web?hl=ja))

#### デメリット
- Node.jsなどのサーバサイドJavaScript実行環境が必要になる
- サーバサイドでレンダリングするのでサーバのCPU負荷が増える

#### アイソモーフィックJavaScript
クライアントサイドとサーバーサイドで同じコードを実行できるようにするためのフレームワークの総称。
クライアント-サーバー間でJavaScriptコードの共通化(主にバリデーションなどのロジック部分)を行う[^3]。
> つまりまとめると、SPA + SSR を両立するために、クライアントとサーバで同じコードが実行できると良くて、それが Isomorphic JavaScript [^4]

#### ユニバーサルJavaScript
アイソモーフィックJavaScriptにおけるJavaScriptコードの共通化の概念について、
クライアントやサーバに限らず、モバイルや組み込みデバイスといった環境でも実行できる、
あるいは、そういった環境に左右されないといった意味でUniversalという呼び方で表現しようといったもの。

# まとめ
サーバサイドレンダリング含めて、今時のweb開発における技術要素についてはっきりとさせられた。
そして、一番重要な概念は仮想DOMなのもわかったからよかった。

あと、調べて思ったけど、vueとかnuxtについて学ぶ中でサーバサイドレンダリングって一言に言われても、
色々と要素技術を含んでるわけだから、分けわかんなくなるよなと思う。

# 参考資料
- [ユーザー体験を向上させるサーバーサイドレンダリングJavaScript — 歴史と利点 - Sundaycrafts - Medium](https://medium.com/@sundaycrafts/%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%BC%E4%BD%93%E9%A8%93%E3%82%92%E5%90%91%E4%B8%8A%E3%81%95%E3%81%9B%E3%82%8B%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC%E3%82%B5%E3%82%A4%E3%83%89%E3%83%AC%E3%83%B3%E3%83%80%E3%83%AA%E3%83%B3%E3%82%B0javascript-%E6%AD%B4%E5%8F%B2%E3%81%A8%E5%88%A9%E7%82%B9-df68cd7cd991)
- [仮想DOMは本当に“速い”のか？ DOM操作の新しい考え方を、フレームワークを実装して理解しよう - エンジニアHub｜若手Webエンジニアのキャリアを考える！](https://employment.en-japan.com/engineerhub/entry/2020/02/18/103000#%E3%83%AA%E3%82%A2%E3%83%ABDOM-vs-%E4%BB%AE%E6%83%B3DOM)
- [Webフロントエンドとサーバーサイドの技術動向をざっくり整理する／JavaScript - "BOKU"のITな日常](https://arakan-pgm-ai.hatenablog.com/entry/2019/04/18/000000)
- [Ruby on Rails - サーバーサイドレンダリングとは？｜teratail](https://teratail.com/questions/22280)
- [はじめに — Vue.js](https://jp.vuejs.org/v2/guide/)


[^1]: [Server Side Renderingについて知るべきこと。Server Side Renderingとは何か？ それによって何が改善されるのか？（前編） ng-japan 2017 － Publickey](https://www.publickey1.jp/blog/17/server_side_renderingserver_side_rendering_ng-japan_2017.html)
[^3]: [Isomorphic Survival Guide - Speaker Deck](https://speakerdeck.com/koichik/isomorphic-survival-guide)
[^4]: [Universal / Isomorphic JavaScript について - Qiita](https://qiita.com/kyrieleison/items/4ac5bcc331aee6394440)
[^5]: [DOM の紹介 - Web API \| MDN](https://developer.mozilla.org/ja/docs/Web/API/Document_Object_Model/Introduction)
[^6]: [DOM Standard 日本語訳](https://triple-underscore.github.io/DOM4-ja.html)
[^7]: [なぜ仮想DOMという概念が俺達の魂を震えさせるのか - Qiita](https://qiita.com/mizchi/items/4d25bc26def1719d52e6#virtual-dom%E3%81%A8%E3%81%AF%E3%81%AA%E3%81%AB%E3%81%8B)