为什么我们选择 Turbolinks 而不是构建 SPA
注:这篇文章最初写于 2016 年,但今天重读一遍,仍然非常有意义。我们仍在使用 Turbolinks,没有更换计划。尽情享受吧!
Changelog.com 不是Rails 应用,但它是Turbolinks应用。仔细想想。
这意味着我们不使用 Turbolinks,因为它是Omakase。我们不使用 Turbolinks,因为我们忘记从 Gemfile 中删除它。我们主动选择了 Turbolinks,安装了它,并将其集成到我们的应用程序中。我认为这让我们非常独特。
自网站开源以来,我们收到的最多的问题是“为什么选择 Turbolinks?” 1
这就是我们选择它的原因(也许您也应该选择它)。
归结为一个词:
勇气实用主义
很容易被新热点所吸引。我比大多数人更容易被吸引,因为我们每周都会和新热点的创造者们讨论他们的新热点。但是,a) 紧跟开源潮流,和 b) 把自己的车拴在每一匹穿着闪亮新鞋昂首阔步的马背上,这两者之间有着很大的区别。
我发现,作为一名开发者,当我了解趋势但又保持谨慎时,效率最高。我一直对事实上的单页应用 (De Facto Single Page App)持怀疑态度。别误会,SPA 是许多应用的合理(通常也是最佳)架构2。然而,如果一个应用程序在不需要的情况下被构建成 SPA,好人也会遭遇坏事。
根据我的经验,我们常常被诱导问自己“为什么这个应用程序不应该是 SPA?”,而不是问自己“为什么这个应用程序应该是 SPA?” 架构应该由应用程序的需求而不是开发人员的愿望来驱动。
当我问自己“为什么新的 changelog.com 应该是 SPA?”时,我面临的棘手问题是,我们有一个(重要的)功能,大声喊着“SPA!”
持久音频播放器位于页脚,并在您浏览页面时继续播放。
但仅此而已。我们没想到还有什么功能或需求需要 SPA。我真的想拆分代码库、增加 JS 负载,并且<gasp>选择一个前端框架</gasp>,就为了拥有一个持久的音频播放器吗?
我内心的技术专家绝对想这么做。实用主义者知道还有更简单的方法。
Turbolinks 领域发生了变化
当 Turbolinks于 2012 年首次发布 Rails 4.0时,它给世界各地的开发人员带来了很多麻烦。
有些人认为这是一个糟糕的想法,但我并不这么认为,因为 GitHub 使用pjax(Turbolinks 的灵感来源)取得了很大成功。
其他人也尝试过,但最终却遇到了一些极端情况、令人沮丧的 bug,以及比宣传更复杂的思维模型。我属于这一类。
换句话说,Turbolinks 没有兑现承诺所以大多数人都把它一笔勾销了,继续他们的生活(有些人甚至嘲笑任何提及它的名字)。但图书馆背后的团队仍在继续努力,不断改进。四年过去了,Turbolinks 已经发生了很大变化。以下是功能和更改的简要列表,可帮助您快速了解:
- 它针对 Turbolinks 5 进行了彻底重写(参见Turbolinks Classic)
- 它不需要服务器端请求检测或替代渲染
- 它不依赖于 jQuery 或任何其他库
- 它包括一个基于 CSS 的加载进度条
- 当资产发生变化时可以重新加载
- 它可以在页面加载时保留元素
- 你可以使用npm/yarn安装它,并使用 webpack 加载它
最后两点正是我们持久播放器所需要的。如果你从 Turbolinks 5 版本发布以来还没看过它,我推荐你去看看。
与 Phoenix 一起使用比阅读其 README 花费的时间更少
我错误地认为在 Rails 之外使用 Turbolinks 会很困难。以下是实际操作:
- 将 Turbolinks 添加到我们的 package.json中的依赖项
- 在app.js 顶部导入 Turbolinks
Turbolinks.start();
在app.js底部调用- 添加
data-turbolinks-permanent
到播放器 div
就这样,我完成了,它真的运行起来了。话虽如此,Turbolinks 也并非完全没有问题。在编写应用程序的 JavaScript 代码时,需要注意一些事项。请务必阅读并理解README 文件中的“构建 Turbolinks 应用程序”部分,这样就万事大吉了。
正如一位明智的高级开发人员曾经说过的:这取决于
我知道,我知道。关于我们应该使用哪些工具和实践的平衡推理并不能成为流行的文章,但它确实有助于构建良好的系统。我在这里并不是要挥手宣布你应该放弃你现在的东西,转而使用 Turbolinks。
我们的应用程序与您的应用程序有很多不同之处,其中一些原因使得我们非常适合提供此解决方案。为了避免您怒气冲冲地给我们发邮件,我列举了其中几个:
- 归根结底,我们是一个内容优先的网站。很少有内容网站需要足够丰富的交互才能使用单页应用 (SPA)。
- 我们没有太多的 JavaScript 和非常少的(面向公众的)表单提交,所以我们还没有遇到 Turbolinks 可能失败的一些更复杂的场景。
- 随着需求的增长,我们可能需要客户端路由。我对此非常怀疑,但确实存在这种可能性。
最终,我们以极少的工程投入实现了目标,网站上线后也获得了广泛好评。大家喜欢我们这款持久的播放器,我也非常感谢 Turbolinks 帮助我们如此出色地完成了这一目标。如果你已经放弃了 Turbolinks,现在可能是给它第二次机会的好时机。
-
第二个问题是:“它怎么这么快?” Turbolinks 可以解决这个问题,但这主要是 Elixir 的错。↩
-
我的第一个 SPA 是在 2010 年,当时我帮助 Grooveshark(RIP)从 Flash 切换到 Web 应用程序。↩