你不应该从 SPA 开始
单页应用(SPA)正作为新 Web 项目的默认选择受到重新审视,许多工程师认为,现代服务端渲染方案(通常借助 htmx、Hotwire 或 LiveView 等工具增强)如今已能以更少的复杂性和运维开销提供相近的交互能力。SPA 的支持者强调,它适合富交互、长生命周期的界面、离线或 local-first 行为,以及 Web 与移动客户端之间共享 API 的场景;而批评者则指出,JavaScript bundle 更重、工具链脆弱、在差网络下性能更差,并且前后端之间的耦合比宣传中更紧。一个反复出现的主题是,架构应当服从产品需求和团队结构:SPA 适合复杂、数据密集且用户会深度停留的应用,但对于更简单的网站,或能从紧密集成的服务端驱动 UI 中获益的小团队来说,它往往是过度设计。
什么时候 SPA 是合理的
- 一些评论者认为,对于复杂、高交互性的 UI,SPA 是合理的(例如功能丰富的管理后台、数据密集型应用、local-first/offline-first 场景)。
- 另一些人建议,只有当会话深度或应用的“原型”表明用户会长时间停留并进行深度交互时,才应选择 SPA,而不是用于简单的博客/营销页面。
- 也有人认为,随着更新的工具(Remix、Livewire、以及像 Blazor/Leptos 这样的 WASM 框架),SPA 会变得更简单。
前端与后端:耦合还是解耦
- 一派认为真正的解耦是不可能的:前端始终依赖后端数据结构;试图隐藏这条边界具有误导性。
- 另一派表示,面向公众的 API 可以同时被 UI 和高级用户使用,并且在一开始就按此设计,配合 mock API 让并行工作成为可能。
- 反复出现的争论是,“backend for frontend”(按视图提供端点)即使在名义上解耦的系统中,也会重新引入紧耦合。
工具链、JavaScript 与扩展性问题
- 很多抱怨集中在 SPA 的工具链上:打包、构建时间、缓存失效,以及随着功能和团队规模增长而不断变大的超大 bundle。
- 有人认为这是 SPA 的固有问题;也有人说,像 esbuild 这样的工具、更简单的设置,或者不使用重量级框架,可以缓解这些痛苦。
- 关于 JavaScript 本身也存在争论:有人认为它天生就很混乱;另一些人则说,“意大利面式”更多是团队实践的问题,而不是语言选择的问题。
UX、性能与网络条件
- 支持 SPA 的人指出,它带来更快的后续导航、更少的 JSON 数据传输、自适应行为,以及更好的离线支持和乐观 UI 机会。
- 反对者则指出,大型 JS bundle 会拖慢首次加载,尤其是在慢网络和性能弱的设备上,而且许多 SPA 在网络问题下会以糟糕且不透明的方式失败。
- 对于在压缩、布局壳和过度获取都纳入考虑后,SPA 是否真的比 HTML 发送更少数据,双方存在分歧。
组织结构、团队与文化
- 一些人认为,架构自然会跟随组织结构图(康威定律);SPA 的拆分通常反映了前端/后端团队分离。
- 另一些人认为,根据组织结构来选择架构有风险;对于小团队来说,采用紧耦合的服务端渲染 UI 的全栈工作流可能更高效。
- 文化上的批评也存在:SPA 部分是因为前端开发者想逃离以后端为中心的框架而兴起的,但也有追逐潮流和“货物崇拜”式采用的因素。
API、移动端与替代方案
- 一方认为,移动应用本来就必须使用 API,因此 SPA 复用是合理的。
- 另一方回应说,在实践中移动端和 Web 往往差异足够大,共享 API 并不会带来多少收益。
- htmx、Hotwire/Turbo、LiveView、Livewire,以及经典框架(Django/Rails/Laravel)等替代方案,经常被提及为更简单、更高产的非 SPA 选项。