news 2026/9/30 1:49:16

htmx 之外:超媒体驱动应用(HDA)替代方案的完整技术全景

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
htmx 之外:超媒体驱动应用(HDA)替代方案的完整技术全景
  • 前端

【免费下载链接】htmx

htmx - high power tools for HTML

项目地址:https://gitcode.com/GitHub_Trending/ht/htmx
点击查看免费下载

导读:本文以 htmx 官方博客《Alternatives to htmx》为基础,系统梳理超媒体驱动应用(HDA)路线下除 htmx 之外的十余个代表性库与框架——从成熟的 Unpoly、Hotwire Turbo,到极简的 htmz、Nomini、fixi.js,再到 SSE 取向的 Datastar 与 Alpine 生态的 Alpine-ajax。读完本文,你将理解这些方案的定位差异、核心机制、体积与适用场景,并能在 htmx 之外为你的服务端渲染应用找到合适的超媒体搭档。

htmx 官方多次强调一个核心观点:超媒体(hypermedia)的思想比 htmx 这个具体实现更重要。在 hypermedia-driven-applications.md 一文中,作者 Carson Gross 将 HDA 架构定义为 MPA(多页应用)与 SPA(单页应用)的"合题":用声明式、内嵌在 HTML 中的语法取代命令式脚本,并让服务器以 HTML 超媒体而非 JSON 数据的形式与应用交互——即坚持 HATEOAS(超媒体作为应用状态引擎) 的 REST 架构约束。

围绕这一思想,生态中涌现了大量与 htmx 殊途同归的实现。本文逐一介绍这些值得纳入选型视野的方案,并结合本仓库中的源码与文章,说明它们与 htmx 的异同、各自的定位,以及什么时候应该"放下 htmx"。

一、先看 htmx 自己的定位与能力边界

在展开替代方案之前,有必要先明确 htmx 本身"完成"了什么。根据仓库 README.md 的说明,htmx 允许你在 HTML 中直接使用 AJAX、CSS 过渡、WebSocket 与 Server-Sent Events,通过hx-*属性构建现代用户界面;它体积小(约 14k min.gz'd)、无依赖、可扩展,是 intercooler.js 的后继者。

README 中提出的四个"为什么"构成了 htmx 的动机:

  • 为什么只有<a>和<form>能发起 HTTP 请求?
  • 为什么只有click与submit事件能触发它们?
  • 为什么只有 GET 与 POST 可用?
  • 为什么只能替换整个屏幕?

通过移除这些"任意限制",htmx 补全了 HTML 作为超文本的缺失能力。这些能力直接体现在 src/htmx.js 的实现中,例如hx-get、hx-post、hx-target、hx-swap等属性(本仓库源码中即有多处对应实现)。与之呼应的是,htmx 的声明式写法还体现了 Locality of Behaviour(行为局部性,LoB) 原则:<button hx-get="/clicked">Click Me</button>的行为一眼可见,不像 jQuery 那样需要跨文件才能拼出完整行为。

理解了这条能力边界,就更容易理解下面这些替代方案各自"补全"了哪一块。

二、Unpoly:Ruby 社区十年打磨的渐进增强框架

Unpoly 是一个成熟的前端框架,尤其在 Ruby 社区被重度使用了超过十年。它提供同类最佳(best-in-class)的渐进增强(Progressive Enhancement)能力,并拥有许多实用概念,例如layers(层级)与精细的表单校验(form validation)。

Unpoly 的作者 Henning Koch 曾接受 Carson Gross 的专访,访谈全文收录在 interviews/henning_koch.md 中。访谈中有几个值得留意的细节,恰好解释了 Unpoly 的设计取向:

  • 它源于 makandra(一家 Rails 咨询公司)在大量客户项目中的模式提炼,本质上是"HTML6 幻想规范"的落地:如果 HTML6 专为服务端渲染应用而设计,它会包含哪些特性?
  • 与 Rails 一样,Unpoly 崇尚"为一切提供强默认值",偏好不显眼的约定优于显式配置——你甚至可以在完全不改动 HTML 的前提下让 Unpoly 接管所有链接和表单。
  • Koch 认为,对大多数中等规模应用而言,超媒体路线往往比 SPA 模型交付更好的结果;浏览器原生处理焦点管理、并发输入、网络不稳定等大量边界情况,而用 JavaScript 模拟页面过渡很难达到同等正确性。

如果你看重渐进增强、成熟度和 Rails 生态,Unpoly 是与 htmx 气质最接近的"重武器"之一。

三、Triptych:把超媒体控制权写进 HTML 规范的提案

Triptych 是一组三份提案,目标是让更通用的超媒体控制能力直接进入 HTML 规范:

  1. 允许在 HTML 中直接使用更多HTTP 方法(不止 GET/POST);
  2. 允许按钮作为独立的超媒体控件(而不只是表单的一部分);
  3. 允许超媒体控件将页面上任意元素作为替换目标。

该项目正在被引入 WHATWG,以争取进入 HTML 规范;同时它附带了一个polyfill,今天就可以用来按提案实现应用。

不难发现,Triptych 的三点主张与 htmx 在 README.md 中提出的四个"为什么"高度重合——它们本质上是把 htmx 已经在实践中赋予 HTML 的能力,尝试以标准化的方式"追认"进规范。从"通用化超媒体控件(generalized hypermedia controls)"这一研究脉络看,htmx 团队自己的极简实现 fixi.js 正是这一思想的另一条路线。

四、fixi.js:htmx 团队自己的极简实现

fixi.js 是htmx 团队对"通用化超媒体控件"的极简实现,重点放在"尽可能小"上,刻意省略了 htmx 中的许多功能。

它的目标数据(按原文档所述):约 3.5k(未压缩、未 minify),压缩后约 1.3k,同时保持可读、可调试,因此可以直接包含进项目而无需任何构建转换。

fixi.js 的价值在于:它证明了"超媒体控件的核心"可以收敛到极小体积,把 htmx 中那些"锦上添花"的功能(如扩展、历史管理、指标等)全部剥掉之后,剩下的本质仍然成立。如果你只需要最基础的 AJAX 式交互、且极度在意包体积,fixi.js 是一个值得关注的极简选项。

五、Datastar:从"htmx 的 TypeScript 重写"独立出来的 SSE 取向方案

Datastar 最初是作为 htmx 的TypeScript 重写 + 现代工具链提案而诞生的,后来发展成独立项目,并采取了一种SSE(Server-Sent Events)取向的超媒体路线。

它的特色在于:把 htmx 与 Alpine.js 的功能合并进一个干净的小包,而且体积比 htmx 更小。换句话说,如果你既想要超媒体驱动的服务端交互,又想要 Alpine 风格的响应式前端能力,Datastar 尝试用单一依赖同时满足两者,并借助 SSE 实现服务器到浏览器的推送式更新。

六、Nomini:最小的"响应式变量 + 局部页面替换"实现

Nomini 是一个拥抱"以 JavaScript 作为简单增强手段"这一原始理念的超媒体实现:它只希望在静态为主的页面之上,添加一层极薄的 LoB(行为局部性)层,从而以最小的客户端代码实现强大的服务端驱动 Web 应用。

按原文档所述,它目前是同时提供**响应式变量(reactive variables)与局部页面替换(partial page swaps)**的库中体积最小者:约 2.8k(minified),约 1.4k(minzipped)。

本质上看,Nomini 可以理解为 Datastar 的微型重实现,或"Fixi + Alpine.js"的组合体——它是面向响应式服务端驱动 UI 的极简、务实积木。这一描述与 htmx-sucks.md 中对"极微库"的调侃形成了有趣对照:Nomini 恰恰选择在"最小化"与"正确性"之间做出自己的权衡。

七、µJS:自带预取、SSE 与 morphing 的无依赖小库

µJS 是一个约5k、无依赖的小型库,实现了大量超媒体思想,特性包括:

  • 预取(pre-fetching)
  • SSE(Server-Sent Events)
  • 基于 idiomorph 的 DOM morphing(morphing 即把新旧 DOM 做最小差异合并,而不是整体替换)

其中 idiomorph 正是 htmx 生态中用于平滑 DOM 过渡的 morphing 方案,µJS 直接将其纳入核心,说明它在"如何优雅地应用服务端返回的 HTML"上与 htmx 共享同一套技术路线。

八、Alpine-ajax:把 htmx 式概念内嵌进 Alpine 生态

如果你已经是 Alpine.js 的用户(Alpine 也是常与 htmx 搭配使用的脚本库),那么值得关注Alpine AJAX:它是一个 Alpine 插件,把类似 htmx 的概念直接集成进 Alpine。

它的定位非常清晰:不引入第二套心智模型,而是让 Alpine 的表达式体系直接获得 AJAX/超媒体交互能力。对于已经在用 Alpine 管理前端状态、只想补上"服务端 HTML 片段交换"这一块的项目,Alpine-ajax 是侵入性最小的选择。

九、Hotwire Turbo:37Signals 出品的成熟前端框架

Turbo 是Hotwire技术套件的组成部分,出自以 Ruby on Rails 闻名于世的37Signals。它是一个打磨精良的前端框架,在 Rails 社区被广泛使用,但同样可以搭配其他后端技术。

值得注意的一点:原文档提到,一些与 htmx 相处不愉快的人转而喜欢上了 Turbo。这暗示两者的体验差异可能集中在约定(convention)与配置(configuration)的取向上——Turbo 更强调开箱即用的框架化约定,而 htmx 更强调"你说了算"的属性化声明。结合 hypermedia-driven-applications.md 的"HDA 风格库"清单(其中同时列出 htmx、Unpoly、TwinSpark、Hotwire),可以看到 Turbo 在作者眼中与 htmx 属于同一超媒体谱系。

十、htmz:用 iframe + location.hash 实现"广义转嵌"的天才小库

htmz 是一个令人拍案叫绝的极简库,它利用了 HTML 的一个既有事实:锚点与表单本来就有target属性,可以指向一个iframe。将这一点与location.hash组合起来,就能实现"广义转嵌(generalized transclusion)"——即把另一个文档的片段动态嵌入当前文档。

原文档强调,这就是该库的全部源码(作者声明"我不是在开玩笑"):

<iframe hidden name=htmz onload="setTimeout(()=>document.querySelector(contentWindow.location.hash||null)?.replaceWith(...contentDocument.body.childNodes))"></iframe>

这行代码的机制可以拆解为:

  1. 隐藏的<iframe name="htmz">作为所有链接/表单的target,让响应在 iframe 内加载而不跳转页面;
  2. iframe 的onload触发后,读取 iframe 的location.hash(即服务端返回内容中约定的目标选择器);
  3. 用document.querySelector(hash)找到页面上的目标元素,再以replaceWith(...contentDocument.body.childNodes)将 iframe 文档体替换进去。

把"页面局部更新"压缩到一行 HTML,这正是超媒体思想"以最小的代价复用浏览器原生能力"的极致示范。它也与 htmx 在 src/htmx.js 中通过属性系统完成的"局部替换"目标一致,只是选择了完全不同的实现杠杆。

十一、TwinSpark:带 morphing 能力、已在生产环境验证的同类库

TwinSpark 由 Alexander Solovyov 创建,与 htmx 类似,特性包括morphing(DOM 变形合并)等。原文档指出,它正在被日活 10 万以上的站点在生产环境使用。

对于担心"超媒体库只适合玩具项目"的开发者,TwinSpark 提供了一个生产级佐证;同时它也被 hypermedia-driven-applications.md 的 HDA 风格库清单明确收录,说明在作者看来它与 htmx、Unpoly、Turbo 处于同一技术阵营。

十二、jQuery:一切的开端——load()与 intercooler.js 的血脉

最后是"元老"jQuery。它的load()方法可以把一个 URL 加载进指定元素:

$("#result").load("ajax/test.html");

这个方法正是intercooler.js(htmx 的前身)的灵感来源之一。如果你已经在使用 jQuery,load()也许就够用了。

这一点在仓库的另一篇文章 htmx-sucks.md 中甚至被拿来作为批评 htmx 的论据——作者(刻意扮演批评者)展示了 2008 年的 jQuery 写法:

$( "#result" ).load( "ajax/test.html" );

与 htmx 的写法:

<button hx-get="/ajax/test.html" hx-target="#result"> Load </button>

两相对照,恰好呈现了超媒体演进的两端:jQuery 用命令式脚本表达"加载到元素",htmx 用声明式属性表达同一件事。而从 locality-of-behaviour.md 的视角看,后者把行为"收拢"到了元素本身,这正是两者在软件设计层面的根本分野。

十三、横向对比:一张表看懂各方案定位

方案体积/规模(原文档所述)核心机制与取向生态/背景最适合的场景
htmx约 14k min.gz'd,无依赖声明式hx-*属性,AJAX/WS/SSE本仓库,intercooler.js 后继想用 HTML 属性直接获得 AJAX 能力
Unpoly成熟大型框架渐进增强、layers、表单校验Ruby/Rails 社区,十年以上看重渐进增强与成熟约定
Triptych规范提案 + polyfill把通用超媒体控制写进 HTML 规范WHATWG 提案关注 HTML 标准演进
fixi.js约 3.5k 未压缩 / 约 1.3k 压缩极简通用超媒体控件htmx 团队极致追求小体积
Datastar比 htmx 更小SSE 取向,htmx + Alpine 合一源自 htmx TS 重写提案想要 SSE 推送 + 响应式前端
Nomini约 2.8k minified / 约 1.4k minzipped响应式变量 + 局部页面替换,LoB 薄层新兴项目最小化的响应式服务端 UI
µJS约 5k,无依赖预取、SSE、idiomorph morphing新兴项目需要预取与 DOM morphing
Alpine-ajaxAlpine 插件把 htmx 式概念集成进 AlpineAlpine 生态已是 Alpine 用户
Hotwire Turbo成熟框架约定优先的页面替换37Signals / Rails想要开箱即用的框架化体验
htmz单行 HTMLiframe + location.hash 转嵌新兴项目极简页面局部更新
TwinSpark同类成熟库morphing,生产验证独立作者需要 morphing 与生产背书
jQuery经典库load()方法全行业历史已在用 jQuery

十四、结论与选型建议

原文档的结论值得反复咀嚼:如果 htmx 不适合你的应用,上面这些库中的某一个,可能恰好能让你继续享受超媒体模型的收益。超媒体世界正在发生大量令人兴奋的事情,而每个库都以自己的方式贡献其中。

结合仓库中的整体论述,可以提炼出几条务实的选型建议:

  1. 先确认路线,再挑工具:HDA 路线的共同前提是"服务器返回 HTML 超媒体、客户端以声明式方式消费它"(见 hypermedia-driven-applications.md)。在这个前提下,htmx、Unpoly、Turbo、TwinSpark 属于同一条主线,选谁更多取决于生态与约定偏好。
  2. 体积敏感的项目:fixi.js、Nomini、htmz、µJS 都把"小"当作第一公民,其中 htmz 甚至只有一行源码,适合作为学习材料或极致精简场景的参考。
  3. 已有 Alpine/jQuery 存量:Alpine-ajax 与 jQueryload()可以以最小侵入融入现有代码,不必推翻重来。
  4. 关注标准演进:Triptych 正在把"通用化超媒体控件"推向 HTML 规范(相关学术脉络可参见 essays/_index.md 中收录的《Hypermedia Controls: Feral to Formal》研究条目),其方向性意义对理解整个生态的走向很有帮助。

最后,正如原文档作者所说:如果这些项目(尤其是较新的那些)对你有帮助,不妨为它们点亮 GitHub Star——对开源开发者而言,那是最有效的精神鼓励之一。而作为技术选型者,你的收获则是:超媒体不是某一家库的专利,而是一条持续演进、百花齐放的架构路线。

  • 前端

【免费下载链接】htmx

htmx - high power tools for HTML

项目地址:https://gitcode.com/GitHub_Trending/ht/htmx
点击查看免费下载
上一篇:gitstatus 架构设计:深入理解守护进程与 Shell 的通信机制
下一篇:告别色彩偏差:Shotcut中用色卡打造电影级LUT预设全指南

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/30 1:49:04

WSL安装与配置全攻略:从零搭建Windows下的Linux开发环境

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/30 1:48:18

大麦抢票脚本教程:5分钟跑通的Python自动抢票完整指南

大麦抢票脚本教程&#xff1a;5分钟跑通的Python自动抢票完整指南 【免费下载链接】Automatic_ticket_purchase 大麦网抢票脚本 项目地址: https://gitcode.com/GitHub_Trending/au/Automatic_ticket_purchase 开抢的那一秒&#xff0c;网页上的"立即购买"还没…

作者头像 李华
网站建设 2026/9/30 1:48:08

FPGA实战解析:TMDS编码原理与RGB转HDMI/DVI高速显示实现

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/30 1:47:25

使用 agent-browser 自动化 Electron 桌面应用:基于 CDP 的完整实战指南

人工智能大模型代码智能体AI Agent桌面应用后端前端CLI 【免费下载链接】ZCode ZCode 是 AI 编程工作台&#xff0c;提供桌面应用、浏览器界面和终端 Agent。本仓库包含客户端、后端服务、共享 UI&#xff0c;以及 Agent CLI 与运行时源码。 项目地址&#xff1a; https://gitc…

作者头像 李华
网站建设 2026/9/30 1:46:37

Open-LLM-VTuber AI 虚拟主播:10 分钟零基础的离线部署路线

Open-LLM-VTuber AI 虚拟主播&#xff1a;10 分钟零基础的离线部署路线 【免费下载链接】Open-LLM-VTuber Talk to any LLM with hands-free voice interaction, voice interruption, and Live2D avatar running locally across platforms 项目地址: https://gitcode.com/Git…

作者头像 李华