我们有时会听到对 htmx 和超媒体的反对意见,通常是以下说法的一些变体:
它可能适用于小型应用,但无法扩展到大型应用。
激发我们思考并提供文章素材总是很危险的,因此让我们深入探讨一下这个说法,看看是否能弄清楚 超媒体驱动应用程序 (HDA) 是否能够扩展。
首先,让我们定义“可扩展性”一词,以及在开发中可以使用该词语的上下文。在软件上下文中,可扩展性通常是指软件处理“更大”事物的能力。这些事物可以是:
“可扩展性”一词的每个含义都需要针对 HDA 进行单独分析。
虽然这对于做出关于自己应用程序决定的单个开发人员来说并不重要,但值得指出的是,网络作为一个分布式网络系统已经非常出色地扩展了。它是我所知的任何情况下最成功的分布式系统。
这对于单个应用程序开发人员来说不一定重要,但它设定了正确的基调:超媒体可以扩展。
超媒体在性能方面是否具有良好的可扩展性?为了回答这个问题,让我们首先看看一些性能可扩展软件的特性。虽然没有权威来源列出这些特性,但大多数具有扩展软件经验的工程师都会同意,此列表中的大多数项目至少是有帮助的:
幸运的是,设计合理的超媒体系统可以拥有所有这些特性。
无状态是 Roy Fielding 创建的 RESTful 架构的约束,用于描述网络。在实践中,许多超媒体驱动应用程序使用会话 cookie 在服务器端管理少量状态,但这是一种众所周知的技术,并没有证明在扩展应用程序时会致命。
水平扩展在超媒体驱动应用程序中有着悠久的历史,并且与大多数超媒体驱动应用程序的无状态性质相吻合:例如,早期的 PAAS 供应商如 heroku(值得铭记)提供对 Rails 驱动应用程序的简单水平扩展。
功能独立性是 HDA 的另一个优势。在 HDA 中,屏幕的端点往往 解耦,而一般的 JSON API 则没有。这意味着这些端点可以独立于彼此进行监控、演化和调整。我们拥有很长的调整这些端点以创建亚 100 毫秒响应时间的历史(例如,通过 SQL 调整,为给定端点最小化数据库查询)。
在端点独立性的基础上支持各种视图,平台性能很容易监控和理解。与可以跨应用程序以多种方式访问的通用 JSON API 不同,您拥有构建特定视图的超媒体的 UI 特定端点。当视图在服务器端构建并且请求通过简单的超媒体交换驱动时,确定导致性能问题的因素变得容易得多。
最后,网络应用程序在 缓存 方面有着悠久而辉煌的历史。HTTP 提供浏览器端的缓存,由标头控制。成熟的服务器端框架如 Rails 提供了在控制器层进行复杂缓存的功能。缓存是 HDA 的第二本能。
所有这些共同使得 HDA 在性能方面具有极高的可扩展性。经过实战考验的性能技术可用于在用户负载增加时扩展您的 HDA。
HDA 方法是否将更多计算推向了服务器端?在某种程度上,这是真的。但是,给定资源的 JSON 表示和其 HTML 表示之间的差异并不像有些人想象的那么大,尤其是在 htmx 基于应用程序中,您不会像往常一样在 HTML 请求中包含标题和页脚信息。网络延迟和数据存储访问通常占据请求时间的大部分,而使用 SQL(或类似的服务器端查询语言)的能力为您提供了优化请求这一方面的机会。
HDA 通常还具有最优的 “每个视图一个请求”,因为在 HDA 中,请求就是您的视图。
由于 HDA 倾向于拥有由 UI 需求驱动的独立端点,而不是通用的 JSON 数据 API,因此功能数量的可扩展性通常非常容易。假设服务器端存在合理的模型-视图-控制器拆分,控制器和模型往往彼此非常独立。当功能真正重叠时,在服务器端开发和测试功能将提供更受控和可测试的环境。
视图可以通过服务器端包含来实现重用,这在几乎所有服务器端模板库中都可以找到,也可以单独维护以避免相互依赖。
所有这些都表明,在合理的应用程序架构下,HDA 往往在功能数量方面非常出色地扩展,尤其是在这些功能本质上彼此解耦的情况下。
功能数量的可扩展性在某种程度上类似于水平扩展:只要它们相对独立,它们就可以很好地扩展(如果它们不独立,HDA 仍然往往会像其他选项一样好地扩展,或者比其他选项更好扩展)。
但是,深度功能怎么样?本身很复杂的功能?
在这里,我们必须将深度功能分为两类:
对于服务器端深度功能,HDA 通常是一个不错的选择。一个很好的例子是像 AI 聊天机器人这样的东西:这是一个非常复杂的服务器端功能,但它通过简单的文本界面与用户交互。许多 AI 聊天机器人 都是使用 htmx 构建的,人们对它的简单性印象深刻。
对于深度客户端功能,HDA 有时不是一个好的选择。我们在关于 何时选择超媒体 的文章中概述了这方面的详细信息。总结一下那篇文章:如果您的 UI 需要快速响应大量的事件(例如,拖动地图视图)或存在无法在批量超媒体交换中更新的重大 UI 依赖关系(例如,电子表格应用程序),超媒体方法将无法正常工作。
但是,我们要注意两点:
我们将要考虑的最后一个可扩展性概念是扩展开发团队的想法。不幸的是,这里我们必须依靠更多主观和轶事性的指标。
根据我们的经验(以及其他人的经验),HDA 似乎允许您用更少的开发人员完成更多的事情。它们还消除了前端/后端拆分以及这种拆分带来的沟通摩擦,因为开发人员负责整个功能。有些人喜欢前端/后端拆分,他们认为这可以通过使团队独立来更好地扩展团队。
我们不同意。我们认为大多数网络应用程序的前端和后端是内在地耦合的,因此,最好的方法是采用接受这种耦合并设计为能够很好地处理更改的架构,而超媒体方法正是这样的(通过统一接口)。
HDA 是否可以扩展到 100 人或更多人的团队?我们无法回答这个问题,因为我们还没有看到这种情况。但它当然可以扩展到 10 人规模。我们可以想象这种方法可以扩展到更高的规模(毕竟它在 Web 1.0 时代就已经做到了),但此时我们只是在推测。
无论如何,我们更喜欢更小的团队。对于任何应用程序来说,10 个开发人员就足够了。
因此,综合以上所有内容,我们得出以下关于超媒体驱动应用程序可扩展性的结论:
HDA 在性能和功能数量方面可以很好地扩展。它们可以在功能复杂度方面扩展,但有一些注意事项。最后,在团队规模方面,结果尚无定论,尽管我们可以说 HDA 方法往往会使团队规模更小,并消除团队之间的沟通摩擦。