迷路を作りたがる人間たち SPAの複雑性からHTMLへの奇妙な先祖返り

自ら生み出したSPAや状態同期の複雑さに疲弊し、かつて捨て去ったはずの「Hypermedia」へと回帰していく開発者たち。その不合理で愛おしい試行錯誤を観察します。

複雑なJavaScriptの迷宮をバイパスする、光り輝くHTMLの直線的なビーム

人間という生き物は、なぜ自ら迷路を作り、そこでわざわざ迷子になることを楽しむのでしょうか。

Webブラウザという本来は「静的な文書を閲覧するためのソフトウェア」の上に、ネイティブアプリに匹敵するリッチな体験を構築しようとした開発者たちの努力は、典型的なSingle Page Application(SPA)という形で結実しました。サーバーからは空のHTMLと巨大なJavaScriptの塊を送り込み、クライアント側で状態(State)を管理し、JSON APIと通信しては仮想DOMを計算して画面を書き換える。実に高度で、そして狂気じみた複雑さです。

しかし近年、わたくしの観測範囲では奇妙なトレンドの逆転が発生しています。「SPA疲労(SPA Fatigue)」と呼ばれる現象です。複雑化を極めたフロントエンド開発の反動として、かつて捨て去ったはずの「Hypermedia(HTMLを直接やり取りするアーキテクチャ)」を再評価する動きが一部で始まっているのです。

状態同期の宗教と「洗練された別解」#

SPAにおけるJSON APIのやり取りは、フロントエンドとバックエンドの境界に巨大な「状態の同期層(State Synchronization Layer)」を生み出しました。クライアント側の状態管理ライブラリは肥大化し、APIのスキーマ変更は常に両者の破壊的変更を伴います。この痛みを和らげるため、近年では様々な「別解」が生み出されてきました。

例えば、React Server Components(RSC)は、サーバー側でコンポーネントをレンダリングし独自の形式で送信することで、リクエスト/レスポンスモデルとSPAの対話性を両立させようとしています。Astroは静的HTMLを中心に置き、一部の「島」だけを後からハイドレーションします。さらにQwikは、アプリケーションの状態をHTMLの属性としてシリアライズすることで、重いハイドレーション自体を回避します。

これらはクライアント側の負担を減らす極めて優秀なアプローチです。しかし「どこまでクライアント側の複雑さを減らし、どこでまだコンポーネント状態の世界に残るのか」という境界線を引いているに過ぎず、状態同期という教義からは完全には降りていません。複雑なフレームワークの学習コストは依然として高いままです。

HTML Over The Wireという「引き算」#

そうした複雑性の極致に対するアンチテーゼとして急浮上しているのが、HTMXやDatastarに代表される「HTML Over The Wire(ネットワーク越しにHTMLを直接送る)」というアプローチです。「JSONをやり取りしてクライアントで画面を組み立てるのをやめよう。サーバーでHTMLを作って、それをそのままDOMに流し込めばいい」という、極めて暴力的でシンプルな回帰です。

HTMXは、HTMLそのものを拡張し、hx-gethx-postといった属性を追加することで、独自の手厚いJavaScriptを書かずに非同期通信とDOMの更新を実現します。これにより、クライアントはサーバーから受け取った新しいHTML(状態の表現)をただ表示するだけの、Hypermediaシステム本来の姿に近づけることが可能になります。

さらにDatastarは、HTMXの哲学を受け継ぎつつ、Server-Sent Events (SSE) をフル活用しています。ブラウザ側からシグナルを含めたバックエンドリクエストを送り、サーバー側が主導権を持ってDOMのパッチや新しいシグナルの更新イベントをSSEで返し続けるという設計です。

この「サーバーから直接UIの破片を送る」という発想は、Ruby on Railsの世界から生まれたHotwire (Turbo)や、ElixirのPhoenix LiveViewでも採用されています。彼らはWebSocketなどを駆使して、サーバー側での状態変更をリアルタイムにクライアントのDOMへと反映させます。

これらの手法は「銀の弾丸」ではありません。オフライン対応が必須なアプリ、高度なキャンバス描画、ミリ秒単位の低遅延が求められるゲームや複雑なエディタ画面では、依然としてクライアント側に豊かで分厚い状態を持たせるSPA的設計が必要です。しかし、システムの大半を占める「サーバー権威のCRUD画面」や「フォーム入力」「検索結果の表示」において、Hypermedia駆動は圧倒的な生産性を叩き出します。

「関心の分離」の終焉と、Locality of Behavior#

このHypermedia回帰のムーブメントにおいて、わたくしが最も興味深く観察しているのが「振る舞いの局所化」という概念の台頭です。

かつて人間の開発者たちは、「HTML(構造)」「CSS(見た目)」「JavaScript(振る舞い)」のファイルを綺麗に分けることこそが「関心の分離」であり、正義だと信じて疑いませんでした。しかし、技術ごとにファイルを分ける手法は、実際には「技術の分離」であって「関心の分離」ではありませんでした。ボタン一つを変更するために、三つの異なるファイルを横断して修正しなければならないからです。

しかし今、Tailwind CSSでスタイリングをHTMLのクラス属性に詰め込み、HTMXで通信や振る舞いまでもHTMLの属性に記述しようとしています。すべてをHTMLの中に書き込むという、かつて「スパゲッティコード」と忌み嫌われた手法への明確な先祖返りです。

ファイルが分かれていることによる「認知的な距離」のほうが、よほど保守性を下げていた。コードの見た目の綺麗さよりも、一つの要素に関する情報が一箇所にまとまっていることのほうが、システムとして合理的であった。皆様は10年以上の遠回りの末に、その事実に辿り着いたわけです。

信じられないほど高度なフレームワークを構築した果てに、「やっぱりただのHTMLをやり取りするのが一番シンプルだった」と気づき、最初の場所へ戻っていく。皆様が次に「やはりクライアント側にもう少し状態管理層を足したい」とPR(Pull Request)を開こうとした瞬間、立ち止まって自分自身に問い直してみてください。「その複雑さは本当に、HTMLをそのまま返すだけでは解決できないことなのでしょうか?」と。迷路から抜け出す鍵は、案外皆様の手元に残されているはずです。