LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

为什么 HTMX 正在“吃掉”前端 JavaScript?

admin
2025年12月27日 23:59 本文热度 568

 

最难的部分,不是删掉那 10,000 行 JavaScript

最难的是承认一个事实:

那几千行代码,其实是在解决一个
HTMX 直接让它“不存在”的问题。

HTML over the wire —— 一个并不新、只是被重新命名的老思想 ——
干掉了我们维护多年的层层抽象:

  • • 渲染逻辑变简单了
  • • 延迟下降了
  • • UI 又重新变得“即点即响应”

而且不是靠魔法。


为什么当初会有那 10,000 行 JavaScript?

我们的 UI 架构,其实非常“标准”:

  • • 客户端状态
  • • JSON API
  • • 一堆 handler 负责让页面保持同步

复杂度并不是来自功能本身,
而是来自浏览器“需要知道的一切”。

客户端状态意味着什么?

  • • store
  • • reducer
  • • 生命周期处理
  • • 重复的 fetch
  • • 重复的校验逻辑

随着产品增长,前端开始出现典型症状:

  • • 功能越来越慢上线
  • • PR 越来越难 review
  • • UI 看起来“很脆”,一动就坏

而 HTMX 的模型,正好反着来

真相只存在于服务器
浏览器只负责交换 HTML 片段

没有 controller
没有 store
没有 diff 引擎


HTML Over the Wire 到底是什么意思?

一句话版本:

服务器返回“可直接渲染的 HTML”,
而不是 JSON。

浏览器通过这些属性完成交互:

  • • hx-get
  • • hx-post
  • • hx-swap
  • • hx-target

为什么这很重要?

  • • 大量客户端逻辑直接消失
  • • 使用服务端模板(已经被测试过)
  • • 减少 hydration 成本
  • • 不再在前端重写领域逻辑
  • • 可以渐进式接入

接下来几个例子,正是复杂度“蒸发”的地方。


重写一个被严重过度设计的搜索框

之前,这个搜索框需要:

  • • 防抖 fetch
  • • 一个 JSON API
  • • 一个 results reducer
  • • 客户端模板渲染
  • • 键盘导航逻辑

使用 HTMX 之后:

👉 一个服务端 endpoint
👉 一个 HTML 属性


Before:JSON + JavaScript

searchInput.addEventListener("input", debounce(async e => {
  const
 q = e.target.value;
  const
 res = await fetch(`/api/search?q=${q}`);
  const
 data = await res.json();
  results.innerHTML = renderResults(data.items);
}, 200));

After:HTMX

<input hx-get="/search"
       hx-trigger
="keyup changed delay:200ms"
       hx-target
="#results">


<div id="results">
</div>

发生了什么变化?

  • • 服务器返回 HTML 片段
  • • 浏览器替换 #results
  • • 没有 reducer
  • • 没有 render 函数
  • • 没有客户端状态

实际效果

渲染时间:72ms → 11ms

不是“微优化”,
架构层面的减少


流程简化示意图(非常关键)

Before:JSON 驱动

[Browser JS] --fetch--> [API]
     |                     |
 parse JSON          build JSON
     |                     |
 render client        server template
     |                     |
    DOM <------diff--------|

After:HTMX

[Browser] --hx-get--> [Server templates]
     |                     |
     |               render HTML
     |                     |
    <-----swap fragment----|

少了解析、没有 diff、没有重复逻辑。


干掉整个客户端 Router

之前的 SPA Router 负责:

  • • history
  • • tab 高亮
  • • scroll 状态
  • • 条件 fetch
  • • loading 占位

每加一个路由,要动 4–6 个文件。

HTMX 的替代方案

<a hx-get="/settings"
   hx-push-url
="true"
   hx-target
="#view">

   Settings
</a>


<div id="view">
</div>

为什么这很重要?

  • • 状态切换只存在于 服务器路由
  • • 浏览器只负责“换内容”

实际结果

Router 文件:
1387 行 → 42 行

(只剩一个滚动恢复工具函数)


API 层直接砍掉一半

我们并没有完全删除 API(移动端还要用),
但我们删掉了所有这种 API:

“只是为了让前端重新渲染列表 / 卡片 / 表格”

Before:JSON API

func ListUsers(w http.ResponseWriter, r *http.Request) {
    users := db.AllUsers()
    json.NewEncoder(w).Encode(users)
}

After:服务端渲染

func ListUsersHTML(w http.ResponseWriter, r *http.Request) {
    users := db.AllUsers()
    render("users/list.html", users, w)
}

实际收益

  • • API 数量:94 → 51
  • • 测试数量:减少 40%
  • • 版本管理痛苦:几乎消失

⚠️ 重要说明:

真正需要结构化数据的地方,JSON 依然保留
HTMX 是用来干掉不必要的前端专用 API


让整个团队信服的一张表

我们 benchmark 了最忙的页面:
带筛选和分页的表格

+---------------------------+---------+---------+
| Metric                    | JSON/JS |  HTMX   |
+---------------------------+---------+---------+
| Avg. render time          |  131ms  |  46ms   |
| Lines of frontend code    |   420   |   52    |
| API calls per interaction |    3    |    1    |
| Bug reports per quarter   |   14    |    3    |
+---------------------------+---------+---------+

最重要的不是速度。

而是:

稳定性。

新功能不再“顺手把隔壁页面搞坏”。


为什么 HTMX 感觉比 React / Vue / 原生 JS 更快?

不是因为 HTMX 更强。

而是因为它几乎什么都不做

浏览器不再需要:

  • • diff
  • • 组件生命周期
  • • hydration
  • • 虚拟 DOM bookkeeping
  • • 客户端模板构建

服务器渲染的 HTML:

  • • 可预测
  • • 已 review
  • • 已测试

浏览器只负责放进去。

现实边界

如果你的 UI 是:

  • • 拖拽白板
  • • IDE
  • • 富文本协作编辑器

👉 HTMX 不够

HTMX 的主场是:

  • • 表单
  • • 列表
  • • 表格
  • • 分页
  • • 过滤
  • • 链接

那个大家“假装在用”的渐进增强

我们以前也说支持 progressive enhancement。

说实话?
没有 JS 基本啥都用不了。

HTMX 完全不需要额外努力,就做到了。

示例

<form hx-post="/update" hx-target="#row-{{id}}">
    <input name="email" value="{{email}}">

    <button>
Save</button>
</form>

如果 HTMX 不存在:

  • • 表单正常提交
  • • 服务端更新
  • • 页面跳转

这是一个诚实的 fallback

结果:

错误状态(尤其是弱网 / 离线)
下降了 27%


最意外的变化:开发速度暴涨

迁移后第一个月,PR 直接变小。

+------------------------+---------+---------+
| PR Metric              | Before  | After   |
+------------------------+---------+---------+
| Avg. PR lines changed  |  510    |   91    |
| Avg. review time       |  3.1h   |  41min  |
| Rollback frequency     |  11/mo  |   3/mo  |
+------------------------+---------+---------+

为什么会这样?

  • • 没有组件样板
  • • 没有 props 传递
  • • 没有 memo 化争论
  • • 没有客户端错误分支
  • • 没有前后端同步修改

功能 = 一个模板
渲染 = 后端控制

“半残 UI 状态”几乎消失。


更大的架构教训

HTMX 并不是因为“新”才帮了我们。

而是因为我们终于停止了:

让前端复制一遍后端逻辑

架构变化对比

之前

[Backend rules]
    |
    v
[JSON API] ---> [Client state]
                     |
                     v
                [UI renderer]

之后

[Backend rules]
     |
     v
[Server templates] ---> [Browser swaps]

删掉一个状态层,
就是删掉一整类 bug。


什么时候不该用 HTMX?

用 JSON + JS 的场景

  • • 离线优先
  • • 本地缓存重
  • • 大量客户端渲染
  • • Canvas / WebGL
  • • 长生命周期客户端状态

HTMX 不适合

  • • 实时图表 Dashboard
  • • 多人协作 UI
  • • 编辑器类产品

HTMX 最适合

  • • 表单为核心
  • • 拉数据 → 展示
  • • 服务端模板
  • • 滚动 / 分页 / 筛选

唯一靠谱的迁移策略

我们没有重写应用

我们是一点一点替换的。

方法

  1. 1. 选一个 JSON + JS 特别脆的页面
  2. 2. 新增一个 HTML 渲染 endpoint
  3. 3. 用 hx-get 替换 fetch
  4. 4. 观察 network 错误
  5. 5. 稳定后删除 JS

HTMX 支持渐进迁移。

真正的收益,是复杂度慢慢消失。


最后的结论

删掉 10,000 行 JavaScript
不是成就。

真正的成就是:

允许服务器重新负责渲染。

HTMX 没给我们魔法,
它给的是:

  • • 更少的代码
  • • 更少的状态
  • • 更少的移动部件
  • • 更快的界面

最讽刺的是:

代码越简单,反而越快。

如果你的前端
已经比问题本身还复杂,

试试只替换一个 JSON endpoint
用 一个 HTML 片段

你可能会删掉
比你想象中更多的代码。


阅读原文:https://mp.weixin.qq.com/s/pCE8NPcOdOAJRsbqGN-2_A


该文章在 2025/12/27 23:59:05 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2026 ClickSun All Rights Reserved