有马

你可能不需要单页面应用

原文链接: journal.plausible.io

随着 React、Angular、Vue.js、Elm 等前端框架的迅速崛起,单页面应用在 WEB 中无所不在。对大多数开发者来说,单页应用已经成为他们‘默认’工具集的一部分,在开始一个新的项目时,由于技术选型形成了思维定势,一些开发者往往直接想到:一个提供 REST API 的服务端,和 React、Angular、Vue、Elm 中的一个前端框架。

这些工具有什么问题吗?当然没有,实际上我喜欢用这些工具进行开发,然而我只会在实际需求将我推向那个方向时才会选择这种架构。如果没有明确的原因去开发一个单页面应用,我在本周每一个工作日都会使用传统服务端渲染的架构进行开发,这种架构很简单并且开发起来更快:

  • 无状态请求 传统的 WEB 服务器是无状态的(HTTP协议是无状态的),这意味着每个端点都可以单独进行推理和测试。相比之下,单页面应用必须在整个会话期间精确地定义状态是如何加载,刷新以及销毁的,同时会引入一些缓存和同步的问题,这些问题是传统服务端渲染不存在的。

  • 浏览器知道如何处理传统的架构 如果你要使用单页面应用路由,你必须多写一些代码用来模拟一些简单的浏览器功能。我已经花了好几个小时用来确保浏览历史被正确的管理,比如加载动画看起来是否平滑,用户通过浏览历史跳转时恢复滚动位置等,真的糟心。

  • 更少、更成熟的工具框架像 Rails、Phoenix、Laravel 等,它们已经出现很长时间了并且很稳定。我在5年前学习了 Ralis,并且我的知识依然完全相关。于此同时我还学了 Gulp,CoffeeScript、BackboneJS 和 SASS ,而这些都已经被新的技术取代 。我们应该减少对 JavaScript 的过度依赖避免 JavaScript 疲劳

  • 免费的搜索引擎优化 单页面应用不得不添加一些基础设施和代码,确保能够被搜索引擎爬虫进行索引。如果你的动态页面需要进行搜索引擎优化,使用传统的服务端渲染实现起来更简单。

这些点意味着单页面应用为开发者带来了更多复杂度和认知负荷。在我的开发经验中,负责度和认识负荷是导致软件出现 Bug 和开发速度下降的最大的因素。

适合单页面应用的场景

如我所说,大多数需求场景下默认的选择应该是传统的服务端渲染应用。然而,有些场景可能强制你选择单页面应用架构:

  • 核心功能具有实时性的应用(如 Slack)

  • 核心功能是富UI交互的应用(如 Trello)

  • 不同场景需要共享很多状态的应用(如 Spotify)

这些产品必须使用单页面架构保证应用稳定运行,这就是为什么对这些公司来说这种架构是正确的选择。然而许多 WEB 应用没有这些需求,那么这些复杂度就可以被避免。

混合解决方案

即使你的应用需要一些实时性的能力或者富交互,你也大可不必对整个应用使用单页面架构。一种好的方式是将小的前端应用嵌入到传统架构中。

GitHub 就使用了这种混合方案,它们整个网站的骨架是传统的 rails 应用程序,某些区域比如 project tabs 就是用嵌入式的前端应用。这是一种结合了两种方式的优雅解决方案,这个方案牛逼之处方在于你可以从简单的地方开始,然后逐步添加更复杂的 UI 交互。

我相信我现在的项目 Plausible 会朝着正确的方向迭代。在未来这个应用的主要 UI 将会是富交互,但是剩下的部分仍然可以使用传统服务端渲染的架构。

一切归结于权衡

就像编程中的所有东西一样,单页面应用和传统服务端渲染的比较中没有唯一的答案。在一些场景下可以使用单页面应用,比如开发一个时髦的实时应用。然而我们需要意识到对开发速度造成的影响。如果不需要单页应用,我们可以避免在应用中加入一些复杂度,并且传统的路由要快得多。

在工作时选择正确的架构会对生产力造成巨大的影响,并最终取得项目的成功。我们要确保两种架构都是我们的开发工具,这样我们可以在不同情况下使用最优方案。