Appendix
言葉の定義
夜空を埋め尽くすほどのフレームワークが生まれては消えていくモダンフロントエンドにおいて、CSR, SSR, SPA, MPAといった用語はそれぞれの立ち位置を表現する必須の用語です。しかしながら、これらですら人によって意味がまちまちであり、議論の土台とするのに苦労します。
ここではこのサイトにおける各用語に明確な定義を与え、技術比較の助けにしたいと思います。皆さんの定義とは異なるかも知れませんが、このサイトではこれで通したいと思っています。
私の考え方としては、下表のように各用語に1つだけ意味を与えています。そしてレンダリングと(ブラウザの)メモリ維持という直交する軸に展開しています。
視点 | 技術 | 名前 | どこでRenderingされるか? | ページ遷移時にメモリは維持されるか? |
---|---|---|---|---|
レンダリング | CSR | Client-Side Rendering | ブラウザ | 不問 |
SSR | Server-Side Rendering | サーバ | 不問 | |
ブラウザ上の メモリ維持 | SPA | Single-Page Application | 不問 | そもそも遷移がない または維持される |
MPA | Multi-Page Application | 不問 | 維持されない |
<head>
タグは保持し、<body>
タグの内容だけを更新しているもの(React Router, Next.jsのLink
タグ、およびHotwire Turbo Driveはこれに当たる)<head>
タグで読み込まれるJavaScript, CSSを再読み込みしないので、レスポンスタイムを短縮できる<a>
や<form>
でナビゲーションをする際、<head>
タグの中身を含めたページ全体をブラウザメモリから消し、まっさらな状態から次のページを描画するもの<head>
タグで読み込まれるJavaScript, CSSを再読み込みするので、JavaScriptの量が多い場合やブラウザのパワーが貧弱な場合はレスポンスタイムが遅い上記の定義に従うと、以下のケースの解釈が容易になります。またそれぞれの技術のメリット・デメリットを上述に従って理解できます。
getServerSideProps()
を使ったページは、状況によってCSRであり、SSRであり、SPAであり、MPAです。
Link
タグを使って画面遷移するときは、サーバからJSONが送られてきます。このJSONを使って、JavaScriptがHTMLをレンダリングして、リンク先のページを画面に表示します。よってCSRですLink
タグを使って画面遷移をするときは<head>
タグを残して、<body>
タグの中だけが(主に)変化します。よってSPAですLink
タグではなく、ただのa
タグで画面遷移をすることもあります。この場合は<head>
タグを含めて、ページ全体がメモリから消去され、次のページはゼロから描画されます。よってMPAですLink
タグを使って画面遷移した場合はgetServerSideProps()
と同様に判断されます「レンダリング」は一般には画像、映像、音声が出力される処理を指しますが、特にReact SPAの場合はこの意味で使われていません。Reactの場合はデータが画面に表示されるまでの工程が複雑ですので、先にこれを解説します。
ReactNode
のツリーに変換されるReactNode
のツリーとブラウザのDOM (画面に表示されているもの)が比較され、差分がブラウザDOMに書き込まれる一般的な用法により近いのは4.のステージだと思いますが、Reactの世界では主に2.のステージを指しているように思います。そこで本サイトでも「レンダリング」は2.の意味で使用します。広義にはブラウザDOMに反映する直前の状態がレンダリングだと考えており、React Server ComponentsのRSC Payloadの生成もレンダリングと考えています。
ReactでSSRを行い、サーバからブラウザにHTMLを送信した場合、このままではページはインタラクティブになりません。つまりクリックなどに反応しません。インタラクティブにするにはHydrationが必要です。
ボタンをクリックに応答させるには、ボタンのHTMLにイベントハンドラを接続する必要があります。イベントハンドラとはクリックしたイベントを受け取り、実行されるJavaScriptのことです。しかしサーバがSSRで生成したHTMLにはイベントハンドラがありません。そのため、インタラクティブにはなりません。
Reactではイベントハンドラを接続するために、JavaScriptをダウンロードし、CSRと同じように完全なウェブページをブラウザの中で作り上げます。これは画面には表示せずに、裏でやります。裏で作られたウェブページにはイベントハンドラがありますので、画面に表示されているボタン等にこのイベントハンドラを繋げます。
これを経て、React SSRのページはようやくインタラクティブになります。
ネイティブなMPAではHydrationは不要です。HydrationをしなくてもHTMLにイベントハンドラがつながり、インタラクティブになります。
JavaScriptはもともとHTMLと分割管理されるように設計されています。そして分割されたものを簡単につなげる仕組みも用意されています。JavaScriptのaddEventListener()
関数により、HTMLに簡単にイベントハンドラがつけられます。ReactのHydrationのように裏でウェブページを再構成するような処理は不要です。
HotwireもネイティブなMPAと同様の方法を採用しており、Hydrationなしでイベントハンドラをつなげます。
SEO (Search Engine Optimization:検索エンジン最適化)はGoogle等の検索サイトの上位に表示させる一連の対策を指します。
各検索サイトは"crawler"もしくは"spider"というボットを使って、自動的にインターネットのウェブサイトにアクセスし、その情報を蓄積します。しかし歴史的にはこのボットはJavaScriptを実行できませんでした。CSRを使った場合はHTMLをレンダリングするためにJavaScriptが必要なので、ボットはCSRサイトの情報を収集できなかったというわけです。つまりCSRを使ったサイトは検索サイトの上位に表示されませんでした。
近年ではGoogleのボットはJavaScriptを実行でき、CSRのサイトからも正しく情報収集ができると考えられています。しかしそれでもJavaScriptを必須とするサイトの方が情報収集に時間を要するという話もあり、不利である可能性があります。残念ながらGoogleを筆頭に各検索サイトはアルゴリズムを非公開にしていますので、この辺りは正確な情報が得られません。またJavaScriptを実行するには多くの処理能力を必要とするので、Google以外の検索サイトについては依然としてCSRのサイトを検索できないと言われています。
確実なSEO対策をするのであれば、サーバがHTMLのレスポンスを返すSSRの方が安心でしょう。