写过三年 htmx,每次想让 AI 边说边出内容都要接一整套 Node.js 后端——今天 htmx 4.0 把这件事从传输层彻底原生化了
写过三年 htmx,每次想让 AI 边说边出内容都要接一整套 Node.js 后端——今天 htmx 4.0 把这件事从传输层彻底原生化了
htmx 4.0.0 在 8 月 28 日正式发布了。这件事值得单独说一说:这次重写从 XHR 换成了 fetch(),带来的最大变化不是性能,而是 streaming——htmx 终于能边收边渲染 AI 的流式输出了,不需要任何后端适配层。
发生了什么
htmx 4 的核心变化是把内部传输层从 XMLHttpRequest 切换到了 fetch() + ReadableStream。XMLHttpRequest 自 1999 年以来就是浏览器异步请求的唯一选择,但它不支持流式响应——服务器必须等全部内容返回,浏览器才能开始处理。
fetch() 返回的 ReadableStream 天然支持分块传输。这意味着 htmx 4 可以在数据到达时立即渲染到 DOM 上,而不必等待完整响应。
这解锁了一个以前只有 Phoenix LiveView 才能做到的场景:让 LLM 边生成内容边展示给用户。htmx 4 官方博客里的原话是——「和 Phoenix LiveView 通过 WebSocket 做 diff streaming 相同的工作流,今天用普通 HTTP/2 加 htmx 也能做了」。
三大破坏性变化
从 htmx 2 升级到 4,有三件事必须处理:
属性继承从隐式变成了显式。在 htmx 2 里,父元素的 hx-confirm 会自动传递给子按钮,不需要额外写任何东西。htmx 4 要求必须加 :inherited 后缀,否则子元素不继承。这是最大的迁移工作量。官方提供了命令行检测工具(npx htmx.org@4.0.0 upgrade-check),可以找出所有需要修改的地方。
事件命名统一了。原来混用 camelCase 和冒号分隔(htmx:beforeRequest),现在统一成 htmx:phase:action 格式(htmx:before:request)。原来的 htmx:xhr:* 系列事件直接移除——既然不用 XHR 了,这些事件就没意义了。
历史记录不再默认写入 localStorage。htmx 2 在后退导航时从 localStorage 读取快照,但快照经常混入第三方 JS 的 DOM 改动,导致恢复时页面状态混乱。htmx 4 改成了后退时重新请求——对大多数用户无感,但如果依赖了本地缓存,需要加 hx-history-cache 扩展。
Streaming LLM 输出能做什么
htmx 4 的 hx-sse.js 扩展现在基于 fetch() + Accept: text/event-stream,HTML 片段可以随到随渲染,不需要等 AI 说完。官方文档给了一个具体例子:写一个 <div hx-get="/chat" hx-trigger="sse:message" hx-swap="innerScroll">,服务器用 SSE 推送 AI 生成的内容片段,浏览器直接渲染。
这意味着做一个 AI 对话界面,不再需要 Next.js 的 API 路由,不需要 Vercel AI SDK,不需要后端流式响应框架。一个返回 SSE 的后端接口,加上 htmx 的几行 HTML 属性,前端就完成了。
存量项目要不要立刻升级
不用。htmx 2 继续长期维护,npm latest 标签在 2027 年初之前不会切换到 4.x。官方明确说「对于无法承受事件模型迁移的项目,坚持 2.x 是完全合理的选择」。
但新项目可以直接用 4.0——streaming 能力是这个版本最重要的新能力,越早积累经验越好。
下一步
现有项目想尝鲜的话:升级前先跑一遍官方检测工具,找出哪些地方需要加 :inherited;然后用测试环境验证 SSE streaming 场景,确认旧的事件监听器是否受影响。htmx 4 完整保留了对 htmx 2 行为的兼容,只是要求显式声明属性继承——大多数不需要子元素继承的场景,改动量很小。
htmx 4 把传输层换成了现代浏览器的标准 API,代价是要求开发者更明确地表达意图。这和浏览器平台这几年的大方向一致——CSS 需要显式声明 @starting-style,权限需要显式 requestPermission,htmx 也在往这个方向靠。
评论区
登录后可评论。