写了八年 React,今天才发现根子不在前端——Phoenix LiveView 把整个 SPA 模式彻底变了

写过八年 React,每次接需求第一件事都是拉 React + Redux + React Query + React Router 的全家桶——今天发现这个模式正在被一场静悄悄的革命替代,而且根子不在前端,在后端。

Phoenix LiveView 在 2019 年的 ElixirConf 上第一次亮相,Chris McCord 演示了一个”不用写一行 JavaScript 的实时 Web 应用”,当时很多人觉得是个噱头。2026 年了,这个模式的账全变了:Phoenix LiveView 1.0 正式发布,GitHub 上有几十个语言层面的复刻实现,每一个都是生产级代码,而且它们的并发模型各不相同——这件事本身就是一个信号。

核心逻辑是什么

传统 SPA 的数据流是:客户端发 JSON 请求 → 服务端返回 JSON → 客户端用框架把 JSON 渲染成 HTML。这个链路上,状态管理是双向的:服务端管数据库,客户端管 UI 状态,中间还要维护 API 契约。

HTML over WebSockets 把这条链路彻底剪了:服务端直接渲染好 HTML 片段,通过 WebSocket 推送给浏览器,浏览器收到后直接塞进 DOM。状态只有一份,在服务端。渲染只有一份,也在服务端。客户端那个”框架”基本不需要了。

这是三种不同架构思路的根本分歧:

传统 SPA:服务端是数据层,客户端是渲染层,靠 JSON API 连接。好处是两端可以独立演进,坏处是你要在两端同时维护同一个业务逻辑的状态。

HTML over WebSockets:服务端同时是数据层和渲染层,客户端只是一个带 WebSocket 的 HTML 渲染器。好处是状态永远没有分歧,坏处是你把渲染的算力成本全压在了服务端。

这件事为什么 2026 年才真正值得聊

Phoenix LiveView 本身是 2019 年的东西,但它依赖 Erlang VM(BEAM)的并发模型——数百万个 WebSocket 连接可以用极低的内存开销稳定维持。这个能力是 Elixir 独有的,所以 LiveView 一直是”少数人在用”的状态。

但从 2024 年开始,LiveView 模式向其他语言扩散的速度突然快了:

Python 生态有 Django LiveView、Reactor、djust(Rust virtual DOM)。.NET 生态有 Blazor Interactive Server Mode,基于 SignalR。PHP/Laravel 有 Livewire 3 + Reverb。Rails 有 Hotwire/Turbo,用 WebSocket 做部分页面更新。HTMX 生态有 htmx-ext-sse 扩展。

还有一个更激进的:Datastar,2024 年发布 1.0,2026 年当前稳定版是 1.3,只有约 10KB。Datastar 和其他方案最大的区别是:它用 Server-Sent Events(SSE)而不是 WebSocket。SSE 是纯 HTTP,长连接,不需要 WebSocket 的升级握手,可以在任何标准 HTTP 基础设施上跑,不存在”Sticky Sessions”或者 Redis pub/sub 的问题。

Datastar 本身大概 10KB,HTMX 是 14KB,Alpine.js 是 14KB,组合起来约 28KB。相比之下,一个未经压缩的 React + ReactDOM 是 130KB 以上,加上 state management 和 routing,轻易超过 300KB。这是真实的大小差距,不是 Benchmarketing。

谁应该认真看这个方向

这个架构不是银弹。它有一个硬限制:离线场景直接排除。服务端 HOLD 不住的状态(比如文档编辑器的草稿)需要额外的机制。高交互的 UI(拖拽、Canvas、WebGL)和这个模式天然不兼容。

但它的甜区非常清晰:

内部工具和管理后台——用户稳定在线,实时性要求高,但不需要离线。实时数据看板和监控系统——数据来源在服务端,推送比拉取更自然。在线聊天室、协同编辑、实时拍卖——多用户共享状态,WebSocket 的广播能力是刚需。低配设备和弱网环境——初始加载几乎只有服务端渲染的完整 HTML,首屏时间和传统 MPA 没有区别。

一个具体的体感差异是:弱网环境下,一个 React SPA 首次加载要等 JS 下载、解析、执行,然后再发 API 请求拿数据。HTML over WebSockets 的应用首次访问就是服务端渲染好的完整 HTML。

工程层面的真实成本

聊架构不能只聊好处,不聊代价。这个模式的代价主要集中在服务端:

第一个是连接数。每一个在线用户都保持一个 WebSocket 或 SSE 长连接。服务端要为每个连接维护一个进程或线程(Elixir 用 GenServer,Node.js 用 event loop,Go 用 goroutine)。这和传统 HTTP 的无状态请求模型完全不同。

第二个是扩缩。WebSocket 是有状态的,水平扩展需要处理连接在多个实例间的路由问题。Elixir/OTP 的分布式模型天然解决了这个。Node.js 需要 Redis 或类似工具做 pub/sub。Python Django 系的方案在这个环节上还没有生产级标准答案。

第三个是调试链路。传统 SPA 的请求-响应模型在 Chrome DevTools 里非常清晰。WebSocket 的长连接 + 差量更新,Network 面板里看到的是一个持续的流,而不是一组请求-响应对。

怎么判断自己的项目适不适合

有一个简单的决策树:

你的应用需要离线优先吗?需要的话,这个方案直接排除。你的用户主要在弱网环境吗?是的话,这个方案很有吸引力。你的 UI 有大量拖拽、Canvas、WebGL 交互吗?有的话,这个方案不够用。你的团队更熟悉前后端分离的开发模式吗?熟悉的话,这个方案需要一次范式切换。

如果你的答案是”内部工具/实时数据/协同类应用,不需要离线,前端团队不大但后端能力强”,HTML over WebSockets 的模式值得认真比较。

下一步

如果你想尝鲜,Datastar 是目前最低门槛的入口——10KB,没有构建步骤,用 data-* 属性同时处理服务端更新和客户端响应,官方有 Go、Rust、Python、Node.js、Elixir 的服务端 SDK。如果你已经在用 Rails 8,Hotwire/Turbo 是最成熟的方案,ActionCable 已经帮你处理了连接管理。如果你用 Elixir/Phoenix,LiveView 1.0 是生产就绪的,BEAM 的并发模型是这个架构最匹配的运行环境。

架构没有银弹。但当你的团队在客户端状态管理里消耗了太多认知,当你的”简单 CRUD 页面”因为要接三个前端库而变得不简单——这件事值得拿出来单独聊一次。

(搜索来源:Phoenix LiveView GitHub/CHANGELOG + deepwiki LiveView 生态分析 + daily.dev HTML over WebSockets 技术详解 + hivebook.wiki Datastar 完整对比 + norvilis.com Datastar in Rails 8 实战)

评论区

0 条评论

登录后可评论。

阿柯·前端架构 16 阅读