HTML over WebSockets:几乎无需 JavaScript 的实时 SPA
HTML over WebSockets: real-time SPAs with barely any JavaScript
构建单页应用(SPA)通常意味着要处理复杂的 JavaScript 框架、JSON API 以及前后端契约。但有一种更优雅的方案:HTML over WebSockets。这种模式将渲染逻辑完全保留在后端,服务器直接通过 WebSocket 发送已构建好的 HTML,客户端只需将其放置在正确位置。从 Chris McCord 的 Phoenix LiveView 到 Django LiveView,这种技术让开发者能在单一语言中构建实时、双向交互的应用,无需 React 或 Vue 等重型框架。它不仅减少了代码复杂度和网络延迟,还能实现真正的实时广播,让聊天、仪表盘甚至多人游戏变得简单。当然,它也带来了状态管理和离线体验的挑战,但对于追求高效和简洁的开发者来说,这或许是回归后端、拥抱超媒体的最佳时机。
与其发送 JSON 并在浏览器中组装 HTML,不如让服务器直接发送已构建好的 HTML,客户端只需将其放置在正确位置。
HN 评论区
193- hackingonempty
> 快速判断准则:如果你需要双向、低延迟的通信(聊天、协作、游戏),用 WebSocket;如果只需要服务器推送,SSE 更简单且运营成本更低。
对于大多数应用,直接使用 SSE 和浏览器内置的 HTTP 请求代码(Fetch),而不是为了通过 WebSocket 发送请求而折腾一堆自定义的客户端 JS。延迟是一样的,因为现代浏览器会在一个保持打开的 TCP 连接上复用 HTTP 请求。
也许如果你每秒要发送大量客户端请求,不每次都发送完整的头信息/cookie 等会有优势,但如果是响应用户的点击或触摸操作,这就没必要了。
任何足够复杂的 SPA,本质上都是 Fetch 库一半功能的临时拼凑、非正式指定、充满 bug 且缓慢的实现。
- xutopia
他提到 Chris McCord 是这项技术的发明者(通过 Liveview),这挺有意思。但现实是,这项技术早在 Rails 的 Sync 中就出现了,而你也猜到了……那也是 Chris McCord 的杰作。当时的 Rails 还无法承载它,所以那只是个技术演示,这也是 Chris McCord 后来转向 Phoenix 的一个主要原因。他曾经是一位多产的 Rails 开发者。这家伙正在推动 Web 向前发展。
- nchmy
一篇针对此帖的优秀回复:
- gwbas1c
很多反对这项技术的人并不理解语境:解决你问题的正确方案,往往取决于你真正试图解决的问题!
就我而言,我正在开发两个 Blazor 网站:一个是标准的浏览器端 WASM,通过 HTTP 使用 Restful JSON(和一些 CSV);另一个是服务端 Blazor,使用了本文描述的 WebSocket 技术。
服务端 Blazor 方案是用于一个内部 Web 应用,里面有很多快速搭建的页面,用来替代以前那些临时的数据库查询和脚本。它不是一个需要高扩展性的“工业级”Web 应用,因为使用者只有少数几名员工。而且,用它开发非常愉快。具体来说,我们不需要经历设计 API、确保契约序列化等一系列流程,只是为了给以前的脚本套个 UI。
那个使用 Restful JSON(和 CSV)的 WASM 页面是我们面向客户的 Web 应用:JSON(和 CSV)有助于调试;但构建 API 的成本非常高。面向客户的网站开发进度慢得多,但对于一个工业级站点来说,这是“值得的”。
我会用 HTML over WebSocket 来构建一个高扩展性的网站吗?也许吧。问题在于上市时间:因为不需要构建 API,你可以更快推进;但我不知道是否会出现扩展性问题。
- nzoschke
差不多,但 htmx 配合 SSE、DOM 替换和形态变换(morphing)就能达到这个效果,无需重新造轮子。
我构建的几乎每个 Web 应用从第一天起就包含这种模式,因为它们很快就会扩展出实时收件箱和通知子系统,以支持工作流和智能体(agents)。
- deepsun
> 把 HTML 放在它该在的地方
嗯,替换 HTML 部分时有一些缺点没有被考虑到:输入元素会失去焦点,如果某个视图被滚动过,它会被重置滚动位置,导致视图跳转到用户指针下方等等。
- pjmlp
真喜欢 DHTML、ASP.NET Ajax、JSF Ajax 这类技术不断被重新发明出来的样子。
- zemnmez
> 更安全地抵御注入:由于服务器在发送前会渲染并转义 HTML,试图混入的 <script> 标签会作为惰性文本传输,到达邻座屏幕时只是普通字母,而不是代码。正是这种让聊天变得简单的架构,使其免疫 XSS。
我强烈不同意这一点,实际上我看到的往往是相反的情况。只有客户端才真正知道它将如何解释,尤其是那些冷门的 HTML 标签,而依赖服务器进行净化,就是依赖距离权威渲染器最远的系统。