SPA + サーバーサイドレンダリング、そのダルさに関する私見
Posted: Updated:
いわゆる SPA + サーバーサイドレンダリングがダルい
唐突ですがおさらいです。
なぜサーバーサイドレンダリング(SSR)が嬉しいかと言えば
- 初期表示の Critical Rendering Path を短縮できる
- SEO における保守信仰にやさしい()
- 古いブラウザ・低性能マシンにやさしい yahoo/fluxible による SPA + Server Rendering の概観 ::ハブろぐ
であり、特に SPA + SSR の文脈においては
Universal Architecture による SPA + SSR は、技術的には過渡期の歪なキメラっぽさが拭いきれませんが、昨今の Web フロントエンドにしては珍しくビジネス的な説得力があります。
- SSR なのでSNSや検索からの流入による初期表示が速い
- SPA なので回遊時のページ遷移も速い
- SSR なので古いブラウザでも CSS のデグラレーション具合でわりと見られる
- SPA なのでダイナミックなトランジションもできる Isomorphic Architecture を実装してるときの細かいアレコレ ::ハブろぐ
のような特徴がありました。
しかし、そもそも Critical Rendering Path の短縮や、Googlebot レンダリングの安定性が他の手段で担保されているならばそれでもよく、これらが SPA + SSR の固有メリットというわけではありません。AMP や App Shell モデル、Service Worker による夢実装など初期表示を速くする試みは増えていますし、Googlebot 対策は prerender.io とかが頑張って....くれる.....かもしれません。
prerender.io、Headless Chrome に対応したらよいけど、PhantomJS と再会してしまったので辛い
Web Components が本格的に普及したら...?
一方で SPA + SSR は引用のとおり 技術的には過渡期の歪なキメラっぽさ(なぜそれらを足し合わせたし、的な) という一面があると考えています。とはいえ思ったよりノウハウと共通認識が成熟しつつあるので、歪なキメラというには失礼な完成度に至りつつはあるようにも感じてはいますが。
例えば Web Components のように、最後はクライアントサイド(ブラウザ)で中身を展開して依存解決しないとレンダリングに至れない仕組みが仕様化されている時点で、SPA + SSR に将来性があるとはあまり思えません。
どうしてもやるなら Web Components 関連仕様の処理を node 等で再実装しないといけません。HTML Imports と Templates の解釈、Shadow DOM 的なスタイルの封じ込めあたりを考慮すれば不可能ではなさそうですが、それが実用レベルになる間に他の技術の発達で SSR が不要になる可能性も高いのではないでしょうか。
ほんとにやるなら SSR で Custom Elements の中身をトコトン展開してレンダリングさせといて、クライアント側でも Custom Elements のアップグレードに身を任せてコンテンツを再構築する...とかになるのかな。
developit/undom とかtmpvar/jsdom で操作可能にしたいのは分かる。眺めてたら Server-side Web Components: How and Why? みたいな面白アイディアはあったし、skatejs/ssr とか Server Components とかもあった。
複雑性の焦点をシステム全体のどこに配置するか
で、なんで肝心の SSR がダルいかというと
- node サーバの仕事が増えると、サーバ側の計算コストが増える
- 負荷の高い処理のためにキャッシュをサーバ側でもたないといけない
- node サーバだのキャッシュサーバだの障害点が増える
という点があげられます。ちなみにモジュールを Isomorphic/Universal に保つのは言うほど難しくないので問題ではありません。他に手段がないならば仕方ない作業コストです。
キャッシュ関係については、HTML レベルのクライアント側キャッシュを是とした App Shell のようなモデルとの相性の悪さも目立ちます。また、どのみちログイン状態があると、SSR に持たせるキャッシュも細切れにせざるを得なくて煩雑になりがちという話もあります。
やはりユーザー体験上の代替手段があるならば、クライアントに計算コストを寄せて完結させるほうが全体の負荷と複雑性を高めすぎない設計に落ち着いてくれる気がします。
SPA 単品かトラディショナルな SSR 単品で済ませたくない?
SPA + SSR 運用の現状を見るに、もちろん直近においては有力な選択肢のひとつだとは思いますが、先を見据えるならどこかで手離れしていくことが望ましい設計パターンになるのではないか、というように考えている次第です。
ということで、神の啓示にしたがって次回は「SSR に対するダルさから App Shell モデルの素振りついでに webpack と和解を試みた」です。
なんでもかんでも SPA にしようぜ!っていう話ではもちろんありません。SSR が不可欠という意識で、SSR 前提のエコシステムのほうも宗派の多様性として存続するなり、当面はケースバイケースの選択肢として在り続ける気がしますよ。
追記というか蛇足: アンサーへの感想
これのアンサーを土曜日のng-japanでする事になりそうだ / “SPA + サーバーサイドレンダリング、そのダルさに関する私見 ::ハブろぐ” https://t.co/OB5P9IpDst
— Yosuke FURUKAWA (@yosuke_furukawa) June 15, 2017
からの
You Need to know SSR // Speaker Deck / みた。 https://t.co/BghRr4dLpn
— あほむっちり (@ahomu) June 17, 2017
です。スライドにも引用(?)いただいたのでちょっとだけ書く。
いちおー、SSR によるパフォーマンス面のメリット(記事冒頭にも簡単に引用紹介してますが)は重々承知した上で、方法論としての SSR がダルいからクライアントサイドに重点を寄せる代替案を模索したいのが自分の考えです。ざっくり HTTP/2 とかネットワーク環境の技術進歩とかで速くなれば不要になるやろー、とかの安直な期待はないです。(あくまで自分は、ですが。他の参考にされた論者の胸中はしらない...)
SPA 単品路線だと、がんばってもキャッシュが回り始める前の初回閲覧でパフォーマンス的な損失が完全には避けづらそうなのは同意します。が、「SSR をやらない = あるフェーズのパフォーマンスを捨てている」というゼロイチの論調に巻き込まれるのはちょっと困っちゃうので、今後ともお手柔らかにお願いいたします。
SSR の煩雑さを解消する銀の弾丸がアンサーでいただけたら最高だったなぁと思いつつ、 ひきつづき SSR もがんばりましょう。c⌒っ.ω.)っ