使用传统服务器端渲染 (SSR) 构建 Web 应用程序,或者换一种说法,构建 超媒体驱动应用程序 (HDA),与使用像 React 这样的单页应用程序 (SPA) 框架构建 Web 应用程序相比,需要一种思维转变。
如果您以 SPA 工程的帽子来对待这种开发风格,您可能会感到沮丧,并错过这种特定架构选择的好处。
以下是 10 个提示,帮助您顺利进行思维转变,利用这种方法的优势并最小化其弱点:
超媒体驱动方法的一个巨大优势是,它使服务器端环境在构建 Web 应用程序时变得更加重要。您的后端不仅仅是产生 JSON,而是用户体验中不可或缺的组成部分。
因此,有意义的是深入研究那里可用的功能。许多较旧的 Web 框架在产生 HTML 方面具有令人难以置信的深度功能。像 服务器端缓存 这样的功能可以在令人难以置信的快速 Web 应用程序和缓慢的用户体验之间做出区别。
花时间学习所有可用的工具。
一个好的经验法则是,争取让您的应用程序响应在 100ms 以内完成,而成熟的服务器端框架有工具来帮助实现这一点。
服务器端环境通常具有极其成熟的机制来正确分解(或组织)您的代码。模型/视图/控制器 模式在大多数环境中都得到了很好的发展,模块、包等工具提供了组织代码的绝佳方式。
而 SPA 用户界面通常通过 组件 组织,超媒体驱动应用程序通常通过 模板包含 组织,其中服务器端模板根据应用程序的 HTML 渲染需求分解,然后根据需要包含在彼此中。这往往导致比组件 기반应用程序中更少、更块状的文件。
另一个要寻找的技术是 模板片段,它允许您仅渲染模板文件的一部分。这可以进一步减少服务器端应用程序所需的模板文件数量。
与 JSON API 不同,您为超媒体驱动应用程序产生的超媒体 API 应该 具有针对特定应用程序 UI 需求的专化端点。
因为超媒体 API 不是设计用于被通用客户端消费,您可以抛开保持它们泛化的压力,并产生特定于应用程序所需的内容。您的端点应针对支持特定应用程序的 UI/UX 需求进行优化,而不是针对域模型的通用数据访问模型。
一个相关的提示是,当您拥有基于超媒体的 API 时,您可以积极重构您的 API,这种方式在编写基于 JSON API 的 SPA 时被强烈劝阻。因为基于超媒体的应用程序使用 超媒体作为应用程序状态的引擎,您能够,而且事实上被鼓励,随着应用程序开发者和用例的变化来改变它们的形状。
超媒体方法的一个巨大优势是,您可以完全重构您的 API 以适应随时间变化的新需求,而无需对 API 进行版本控制甚至文档化。
当使用 SPA 方法构建应用程序时,数据存储通常位于 JSON API 后面。这种间接层往往阻止前端开发者充分利用数据存储中可用的工具。GraphQL 可以帮助解决这个问题,但带来了安全相关问题,这些问题似乎没有被许多开发者很好地理解。
另一方面,当您在服务器端产生 HTML 时,创建该 HTML 的开发者可以完全访问数据存储,并利用例如 SQL 存储中的 连接 和 聚合函数。
这将远更丰富的表达能力直接置于产生 HTML 的开发者手中。因为您的超媒体 API 可以围绕您的 UI 需求构建,您可以调整每个端点以发出尽可能少的数据存储请求。
一个好的经验法则是,每个请求应争取有三个或更少的数据存储访问。
模态窗口 在当今许多 Web 应用程序中变得流行,几乎成为标准。
不幸的是,模态窗口与 Web 的许多基础设施不兼容,并引入了客户端状态,这可能难以(尽管并非不可能)与基于超媒体的方法干净集成。
考虑使用替代方案,如 内联编辑,而不是模态窗口。
许多 SPA 开发者在转向 HDA 方法时面临的问题是,他们查看当前的 SPA 应用程序,并想象使用超媒体 完全 实现它。虽然 htmx 和其他面向超媒体的库显著缩小了基于超媒体的应用程序与 SPA 之间的交互差距,但该差距仍然存在。
正如 Roy Fielding 所说 关于 Web 的 REST-ful 网络架构:
然而,这种权衡是,统一接口会降低效率,因为信息以标准化形式传输,而不是特定于应用程序需求的形式。
接受特定 UX 的略微不太高效和交互式的解决方案可以在构建 Web 应用程序时为您节省巨大的 复杂性。
不要让完美成为好的敌人。
在您的 Web 应用程序的某个点,超媒体方法本身可能就不足以应对。
一个很好的例子是重新排序事物列表。这可以通过“纯”超媒体来完成,通过点击上下箭头或在项目旁边有顺序 # 下拉菜单。(我很惭愧地承认我构建过两者!)
但这种体验与人们习惯的相比很糟糕:拖放。
在这种情况下,使用前端重的“交互岛屿”方法是完全可以的。
考虑 SortableJS 示例。在这里,您有一个复杂的交互区域,允许拖放,并通过事件与 htmx 和更广泛的超媒体驱动应用程序集成。
这是将更丰富的 UX 封装在 HDA 中的一种优秀方式。
脚本 明确是 Web 架构的一部分,采用超媒体方法的开发者不应该害怕使用它。当然,有脚本和脚本之分。
尽可能,您应该尝试使用 面向超媒体的脚本 方法,保留超媒体交换作为与服务器通信系统状态变化的主要机制。
例如,由 alpine.js 和 hyperscript 启用的内联式脚本也值得探索,因为它将您的脚本重新聚焦到超媒体 (HTML) 本身,并对您能编写的代码量施加审美约束。
最后,不要对使用超媒体教条主义。归根结底,它只是另一种技术,具有其自身的 优势和弱点。如果应用程序的特定部分,或者整个应用程序,需要比超媒体所能提供的更交互的东西,那么就使用能够提供的技术。
只需熟悉 超媒体能做什么,这样您就可以作为一名知情的开发者做出决定。
希望这些提示能帮助您更有效地和平稳地采用超媒体和服务器端渲染作为工具。它不是完美的客户端-服务器架构,并且涉及明确的权衡,但它对许多 Web 应用程序(远超当今大多数 Web 开发者所怀疑的)非常有效,并在这些情况下提供了更简单的整体开发体验。