
2026/08/13 1:51
WebSocket を通じた HTML:JavaScript は最小限のリアルタイム SPA
RSS: https://news.ycombinator.com/rss
要約▶
Japanese Translation:
単一ページアプリケーション(SPA)において、重い JavaScript に依存するのは開発者が WebSockets に対して HTML を採用する場合には不要である。このアーキテクチャは Chris McCord が Phoenix LiveView で開拓し、レンダリングロジックをすべてバックエンドにシフトさせ、Elixir の Phoenix、Ruby の Hotwire、Python の Livewire、C#'s Blazor、PHP の Livewire 3 および agnostic ツールの htmx を含むフレームワークにおいて、ロジックとプレゼンテーションを一つの言語で処理することを可能にしている。複雑なフロントエンドフレームワークまたは精巧な API コントラクトの代わりに、システムは HTML 内でリアルタイムサーバーサイドの状態管理を直接行うことで開発を簡素化する。
主な利点は固有のセキュリティとパフォーマンスであり、クロスサイトスクリプティング(XSS)攻撃に対する組み込みの保護を提供しつつ、恒常的なポーリングや JSON データの前処理なしに瞬時の双方向更新を維持する。クライアントの役割は WebSocket チャンネルへの接続および受信された HTML の DOM への挿入に限られる。このアプローチにより、コンテンツは検索エンジン最適化(SEO)に対して直ちにインデックス可能となるが、クロワラーはその後続する WebSocket 更新を見ることができないため、重要なコンテンツは初期レスポンスに存在する必要がある。サーバー送付イベント(SSE)は通知や AI ストリームなどの一方通行通信のより安価な代替手段を提供するが、マルチプレイヤーゲームやライブダッシュボードのような複雑なアプリケーションでネイティブなクライアント対サーバー通信が必要となる場合、フル WebSockets のインタラクティビティに匹敵することはできない。究極的には、企業はフロントエンドの複雑性の大幅な削減とスケーラブルなリアルタイムソリューションのために、より高いサーバーリソース(共有状態機構としての Redis などをしばしば必要とする)をトレードしている。
Text to translate:
The text argues that Single-page Applications relying on heavy JavaScript are unnecessary when developers adopt HTML over WebSockets. This architecture, pioneered by Chris McCord with Phoenix LiveView, shifts all rendering logic to the back-end, allowing a single language to handle both logic and presentation across frameworks like Elixir's Phoenix, Ruby's Hotwire, Python's Livewire, C#'s Blazor, PHP's Livewire 3, and agnostic tools like htmx. Instead of complex frontend frameworks or intricate API contracts, the system simplifies development by enabling real-time server-side state management directly in HTML.
The primary benefit is intrinsic security and performance; it offers built-in protection against Cross-Site Scripting (XSS) attacks while maintaining instant bidirectional updates without needing constant polling or JSON data preprocessing. The client's role shrinks to merely connecting a WebSocket channel and injecting received HTML into the DOM. This approach ensures content is immediately indexable for Search Engine Optimization, although crawlers do not see subsequent WebSocket updates, meaning critical content must be present in the initial response. While Server-Sent Events (SSE) offer a cheaper alternative for one-way communication like notifications or AI streams, they cannot match the interactivity of full WebSockets for complex applications like multiplayer games or live dashboards where native client-to-server communication is needed. Ultimately, companies trade higher server resources (often requiring shared state mechanisms like Redis) for significantly reduced frontend complexity and scalable real-time solutions.
本文
WebSockets を通じた HTML:SPA の近代化アプローチ
シングルページアプリケーション(SPA)の構築は、通常、以下の複雑なパズルとして扱われます。
- ビュー用 JavaScript フレームワーク
- JSON を提供する API
- 相互理解のための契約書(API スペック)
この専門的なアプローチは一般的ですが、唯一の方法ではありません。本稿では、より簡潔なアプローチである**「WebSockets を通じた HTML」**を取り上げます。
核心的な考え方
JSON でブラウザを操作するのではなく、サーバー側で構築された HTML を送信し、クライアントがそれを配置します。これにより以下のメリットがあります。
- レンダリングロジックの一元化:バックエンド(単一言語)で維持することで、フロントエンド依存度を削減。
- 契約書の排除:従来の API 定義や複雑な通信プロトコル不要。
- ハイパーメディア:コンテンツが構造を定義し、ブラウザがそれに基づいて動作するモデル("HTML Over The Wire")。
伝送手段の 3 つの変種
通信特性を決定するチャンネルの選択は重要です。主な選択肢は以下の通りです。
| チャンネル | 特徴 | 代表的な例 |
|---|---|---|
| HTTP | リクエスト単位で通信 | htmx, Unicorn |
| SSE (Server-Sent Events) | サーバー→クライアントの一方通行継続チャンネル | Datastar |
| WebSockets | 恒久的な双方向チャンネル | Phoenix LiveView, Django LiveView |
本稿では、最小限の JavaScript で SPA を構築し、リアルタイムかつ双方向通信を実現する 「WebSockets を通じた HTML」 に焦点を当てます。
起源と実証
Elixir エコシステムの人気フレームワークである Phoenix の創設者 Chris McCord が 2019 年の ElixirConf で提唱しました。この技術は後に「LiveView」として定着しています。
- 驚異的なパフォーマンス:React や Angular、Vue といったレンダリング用 JS を使用せずとも、リアルタイムに動作する Twitter クローンを作成可能。
- 生産性の向上:バックエンドに留まったまま、良好なユーザーエクスペリエンスを実現。
- 影響の拡大:Elixir の枠を超え、他の言語でも同様の「ワイヤーを介した HTML」の実装が開発されています。
仕組みは?
クライアントサイドでも JavaScript が使われますが、役割は異なります。
ロールの違い
| システム | サーバーの役割 | クライアントの役割 |
|---|---|---|
| 従来方式 (JSON) | データを JSON で送信 | 解釈し、レンダリングエンジンで DOM を構築 |
| WebSocket HTML | HTML とロジックをすべて送信 | 受け取った HTML を配置し、イベント監視のみ |
比較:従来方式 vs. WebSocket アプローチ
1. 従来のシステム(HTTP + JSON)
ブラウザは HTTP リクエストを行い、JSON をパースしてレンダリングします。
sequenceDiagram participant C as ブラウザ participant S as サーバー C->>S: 1. HTTP リクエスト (GET /api/article/2/) S->>S: 2. データベースを照会 S->>S: 3. JSON を構築 S-->>C: 4. JSON を返却 C->>C: 5. JSON のパース C->>C: 6. レンダリングエンジンで HTML を構築
2. WebSockets を通じた HTML
リクエストは永続チャンネルを伝播し、サーバーから組み立てられた HTML が直接返されます。
- 完全な WebSocket サイクル(接続含む):
sequenceDiagram participant C as ブラウザ participant S as サーバー (バックエンド) C->>S: 1. WebSocket 接続を開き認証を行う Note over C,S: 単一の永続的なチャンネル C->>S: 2. テキスト送信:"I want /article/2/" S->>S: 3. データベースを照会 S->>S: 4. HTML をレンダリング S-->>C: 5. 組み立てられた HTML/CSS/JS を返却 C->>C: 6. HTML を適切な場所に配置 Note over S,C: サーバーは変更をプッシュ可能(ブロードキャスト)
利点
このアーキテクチャの本質的なメリットは以下の通りです。
- 単一のレンダリングエンジン:複雑なフロントエンドフレームワーク不要。
- API の不要さ:中継層を排除し、サーバーが直接 HTML を送信。
- サーバーサイドの状態保持:プロセス単位でクライアント状態を記憶(ステートレスな htmx と対照的)。
- 直接的なデータベースアクセス:JSON や GraphQL の仲介なし。
- 真のリアルタイム性:ポーリングを行わず、即座に更新を受信可能。
- ブロードキャスト機能:チャットやダッシュボード、マルチプレイヤーゲームの容易な実装。
- 低いレイテンシとトラフィック:永続接続により TCP ハンドシェイクを省略。
- 最小限の JavaScript:重厚なフレームワークを使わず、軽量な SPA 構築が可能。
- 合理的な SEO:サーバーサイドレンダリングにより、初期レスポンスでインデックス可能。
- XSS に対する安全性:サーバー側での HTML エスケープにより、悪意あるスクリプトの実行を防ぐ。
欠点と制限事項
導入前の検討が必要な点もあります。
- リソース集約的:サーバーは常時接続を開けておく必要があり、メモリ消費が増加します。水平スケーリングには Redis などでの状態共有が必須(Django Channels など)。
- レイテンシへの感受性:物理的なネットワーク遅延が高い場合、「一瞬」という感覚が損なわれます。
- オフライン対応の欠如:接続切断時はサイト停止するため、再接続ロジックやフォールトトレランス設計が必要です。
- 学習曲線:単なる
タグの追加ではなく、LiveView パターンや WebSocket サーバー設定を理解する必要があります。<script>
現在の状況:既存フレームワーク一覧
「LiveView パターン」は双方向が必要なシナリオ向けですが、HTTP や SSE も特定の用途で共存しています。
| 言語 | フレームワーク | 伝送手段 | サーバープッシュ対応? | ステータス |
|---|---|---|---|---|
| Elixir | Phoenix LiveView | WebSocket | はい | 成熟済み (LiveView 1.0: 2024 年 12 月) |
| Ruby | Hotwire (Turbo + Stimulus) | HTTP + WS/SSE | はい | Turbo 8 でモルフィング対応 |
| Python/Django | Django LiveView | WebSocket | はい | 活発(実装あり) |
| Python/Django | Reactor | WebSocket | はい | 活発 |
| Python/Django | djust | WebSocket | はい | 新作(Rust VDOM を使用) |
| C#/.NET | Blazor (Interactive Server) | WebSocket (SignalR) | はい | .NET 9、レンダリングモード対応 |
| PHP/Laravel | Livewire 3 + Reverb | WebSocket | はい | Reverb は Laravel 独自 WS サーバー (2024 年) |
| 汎用 (JS) | htmx | HTTP + WS/SSE 拡張 | はい(拡張機能) | バージョン 2.0 |
| 汎用 (JS) | Datastar | SSE | はい | バージョン 1.0 |
SSE:コスト効率の良い選択肢
双方向チャンネルを維持する WebSockets は強力ですが、コストがかかります。主にサーバー→クライアントへのプッシュ(通知、ライブフィードなど)で良い場合は、SSE (Server-Sent Events) が最適です。
SSE の利点
- 単純なインフラストラクチャ:ステートフルなプロセス維持不要。
- ロードバランシング容易:スケーリングが簡単。
SSE の制限事項
- 一方通行のみ:サーバーからプッシュ可能ですが、クライアント→サーバーは別 HTTP リクエストが必要です。
- テキストのみ:UTF-8 運搬だがバイナリ不可(WebSocket と対照的)。
- 重い双方向業務には不向き:チャットやゲームなどには WebSocket が適しています。
htmx を使用した実装例
チャンネルを属性で宣言し、受信 HTML が自動配置されます。
<div hx-ext="sse" sse-connect="/updates" sse-swap="message"> リアルタイムコンテンツがここに表示されます </div>
- ブラウザのネイティブ
を使用。EventSource - 自動再接続に対応。
簡単なルール
- 双方向、低レイテンシが必要か(チャット、コラボレーション、ゲーム)?
- 👉 WebSocket を使用
- サーバーからのプッシュのみで良いか(フィード、通知)?
- 👉 SSE が単純で安価
最終的な注記
WebSockets を通じた HTML は万能ではありません。伝送手段は課題に合わせて選択すべきです。
- リアルタイムの往復通信(チャット、ライブパネル)👉 WebSocket
- サーバーからのプッシュのみ(フィード、通知)👉 SSE
- リクエストとレスポンス(標準的な CRUD)👉 HTTP を介した htmx
すべてのプロジェクトに最適解があるわけではありませんが、重要な核心は以下の思想です。
*JSON の代わりに HTML を送信し、単一言語に留まり、API や契約書、そしてフロントエンドの半分を削除してください。
トレンド追従ではなく、良いアーキテクチャを信頼しましょう。
参考文献
- Phoenix LiveView:クライアントごとの状態を持つ正則のパターン公式ドキュメント。
- Phoenix Blog:LiveView 1.0 の発表(2024 年 12 月)。
- Hotwire:“HTML Over The Wire”の起源;Turbo は主に HTTP を使用。
- htmx docs:HTTP 介したハイパーメディア;ステートレスで WS/SSE は拡張機能対応。
- Turbo Handbook:ページリフレッシュと Turbo 8 のモルフィングによる変更部分更新の詳細。
- idiomorph:DOM モルフィングライブラリ。
- Datastar:WebSocket に代わって SSE に賭けるハイパーメディアフレームワーク。
- MDN:Server-Sent Events(自動再接続、Last-Event-ID)の使用法。
- Laravel Reverb:PHP によるサードパーティ拡張なしのリアルタイム動作証明。
- Microsoft Learn:ASP.NET Core Blazor Interactive Server モードは SignalR を介して動作。