1. 引言构建单页应用Single - page ApplicationSPA通常需要一个用于绘制视图的 JavaScript 框架、一个提供 JSON 数据的 API以及两个独立的代码库它们还得通过契约来实现相互理解。这是一种被广泛接受且成熟的方案但并非唯一选择。另一种方法 HTML over WebSockets 虽并非新事物但近年来逐渐受到关注。其核心思想是服务器直接发送已经构建好的 HTML而不是发送 JSON 数据让浏览器来组装 HTML客户端只需将接收到的 HTML 放置到合适的位置即可。所有的渲染逻辑都留在后端使用单一语言无需契约或 API。这种模式也被称为超媒体或 HTML over the wire。HTML 的传输方式决定了通信的延迟和双向性主要有 HTTP、SSE、WebSockets 三种变体。本文将重点探讨 HTML over WebSockets它是具备实时性和双向性的变体借助它几乎无需使用 JavaScript 就能构建 SPA使用单一语言无需契约并且只需一个渲染引擎。接下来将了解它是什么、如何工作以及与基于 HTTP 或 SSE 的同类方案相比它在哪些方面更具优势。2. 起源Chris McCord 是 Elixir 生态系统中最流行的框架 Phoenix 的创造者。在 ElixirConf 2019 上他展示了一项名为 LiveView 的技术仅用 15 分钟就构建了一个实时运行的 Twitter 克隆应用而且没有添加任何用于渲染的 JavaScript也未使用流行的框架如 React、Angular、Vue 等来管理视图。这证明了开发者可以专注于后端开发同时保持高效和良好的性能。从那以后这个解决方案越来越受欢迎启发了其他开发者在其他编程语言中实现基于 WebSockets 传输 HTML 的方案。3. 工作原理乍一看客户端似乎没有使用 JavaScript但实际上还是会用到。不过它的作用不是渲染而是通过 WebSockets 创建通信通道并将接收到的 HTML 放置到正确的位置此外还负责一些次要任务如动画效果、事件处理等。McCord 的解决方案是直接向客户端发送无需预处理的 HTML而不是 JSON。这样一来就把渲染的负载和所有逻辑都转移到了后端。使用 WebSockets 能让服务器在无需客户端请求的情况下立即发送新内容。传统系统中在网页上发起一个 HTTP 请求浏览器启动操作然后收到一个包含所有原始信息的 JSON 响应接下来需要对这个 JSON 进行解析并构建相应的 HTML。而使用 HTML over WebSockets 时同样的请求会通过一个永久通道传输并且响应直接是已经组装好的 HTML中间无需经过 JSON 这一步。而且由于通道不会关闭服务器甚至可以主动推送更改无需客户端请求。忽略初始连接和身份验证使用 WebSockets 的流程简单、优雅且高效。客户端负责将 HTML 放置到正确的位置并监听事件而服务器处理其他所有事情。无需担心客户端状态或渲染逻辑因为所有这些都在后端完成。完整且复杂的流程包括打开连接和身份验证也展示了这种方案在架构上相比其他解决方案具有一些内在的优势。4. 优势HTML over WebSockets 具有诸多优势单一渲染引擎减少了复杂性无需构建 API服务器直接生成 HTML 并发送给客户端无需中间层状态存储在服务器每个连接的客户端都有一个对应的进程来记录其状态直接连接数据库无需 JSON 或 GraphQL 中间层具有真正的实时性客户端能够尽快收到更改无需轮询服务器具备广播功能服务器可以同时向所有连接的客户端推送更改减少流量和延迟单一持久连接避免了每次交互时重复进行 TCP 握手和发送 HTTP 头几乎无需 JavaScript 构建 SPA无需使用 React、Angular 或 Vue 等重量级框架有良好的 SEO由于 HTML 在服务器端渲染首次加载的内容可以被搜索引擎索引更安全防止注入攻击这种架构在使聊天应用变得简单的同时也使其对 XSS 攻击具有免疫力。5. 缺点HTML over WebSockets 也存在一些缺点服务器资源需求更高服务器需要保持 WebSocket 连接打开并且通常会在内存中存储每个客户端的状态进行水平扩展时需要共享这些状态但只有在同时连接的客户端数量非常大时这才会成为真正的问题并且通过精心设计可以缓解这个问题存在延迟问题如果物理延迟较大实时交互的 “即时感” 会受到影响无法离线工作如果连接中断网站将停止工作需要设计重新连接的体验和容错机制学习曲线较陡运行 WebSocket 服务器并非易事需要学习如何处理 LiveView 模式这比简单引入一个