2026-05-14HTMX全栈开发Web后端架构

HTMX 革命:后端全栈的文艺复兴

话说 2021 年,有个叫 Big Sky Software 的公司发了一个库叫 [HTMX](https://htmx.org/),当时前端圈几乎没人当回事。彼时 React 生态正如日中天,"一切皆组件"的口号喊得震天响,谁会多看一眼这个看起来像是在 HTML 里塞了一堆 `hx-` 前缀属性的奇怪东西?

biluo·6131 words

话说 2021 年,有个叫 Big Sky Software 的公司发了一个库叫 [HTMX](https://htmx.org/),当时前端圈几乎没人当回事。彼时 React 生态正如日中天,"一切皆组件"的口号喊得震天响,谁会多看一眼这个看起来像是在 HTML 里塞了一堆 hx- 前缀属性的奇怪东西?

结果呢?四年过去,HTMX 的 GitHub Star 从几千飙升到近五万,成了 2024-2025 年最受关注的 Web 技术之一。这背后不是营销胜利,而是一次对 Web 开发根本性错误的集体反思。

前端焦虑的根源:混淆了关注点

我们先退一步想想:为什么 React/Vue 一统江湖之后,Web 开发反而更累了?

看看一个典型 SPA 的问题:

1. 后端只提供 JSON API,变成了"数据管道"

2. 前端承担所有 UI 逻辑,复杂度爆炸

3. 每次改个小功能,要改 API、改 TypeScript 类型、改前端组件、考虑状态管理

4. SEO?SSR 水太深

5. 加载性能?bundle size 越滚越大

问题的根源在于:我们把本该属于后端的 UI 渲染责任强行外包给了浏览器。HTTP 本来就是为文档交换设计的,我们却非要用它传 JSON 再让 JS 渲染成 HTML。这不是技术的胜利,这是架构的妥协。

HTMX 的核心洞察:HTTP 原语即 UI

HTMX 的设计哲学极其简单:让服务器返回 HTML 片段,而不是 JSON,让浏览器直接替换页面局部

`html

Loading...

`

服务器返回的只是 partials/users 这个 URL 对应的 HTML 片段,HTMX 自动拿到后替换 #user-list 容器。没有 JS、没有构建工具、没有状态管理

这意味着什么?你的后端模板引擎(Jinja2、Blade、Twig、Go templates)就是你的 UI 框架

实战:Flask + HTMX 构建真实应用

光说不练是耍流氓。我用一个真实的 TODO 应用来展示这个模式有多高效。

项目结构

`

todo_app/

├── app.py # Flask 后端

├── templates/

│ ├── base.html # 布局模板

│ ├── index.html # 主页面

│ └── _todo_row.html # 单条 TODO 的局部模板

└── static/

└── htmx.min.js

`

后端:Flask 应用

`python

from flask import Flask, render_template, request, redirect

from flask_sqlalchemy import SQLAlchemy

from datetime import datetime

app = Flask(__name__)

app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///todo.db'

app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

db = SQLAlchemy(app)

class Todo(db.Model):

id = db.Column(db.Integer, primary_key=True)

title = db.Column(db.String(200), nullable=False)

completed = db.Column(db.Boolean, default=False)

created_at = db.Column(db.DateTime, default=datetime.utcnow)

# 主页

@app.route('/')

def index():

todos = Todo.query.order_by(Todo.created_at.desc()).all()

return render_template('index.html', todos=todos)

# 添加 TODO(返回 HTML 片段,不是 JSON)

@app.route('/todos/add', methods=['POST'])

def add_todo():

title = request.form.get('title', '').strip()

if not title:

return '', 400

todo = Todo(title=title)

db.session.add(todo)

db.session.commit()

# 返回新行的局部模板,用于 HTMX 替换

return render_template('_todo_row.html', todo=todo)

# 切换完成状态

@app.route('/todos//toggle', methods=['POST'])

def toggle_todo(id):

todo = Todo.query.get_or_404(id)

todo.completed = not todo.completed

db.session.commit()

return render_template('_todo_row.html', todo=todo)

# 删除

@app.route('/todos//delete', methods=['DELETE'])

def delete_todo(id):

todo = Todo.query.get_or_404(id)

db.session.delete(todo)

db.session.commit()

return '', 200

`

关键点在这里:三个路由返回的都是 render_template() 渲染的 HTML 片段。后端天然知道怎么渲染自己的数据,不需要额外的序列化层。

前端:HTMX 模板

`html

HTMX TODO

hx-target="#todo-list"

hx-swap="beforeend"

hx-on::after-request="this.reset()">

`

`html

  • hx-swap="outerHTML">

    {{ todo.title }}

  • `

    注意 hx-swap="delete":HTMX 会把被替换的元素从 DOM 中删除。

    完整效果

    整个应用只有:

    • 1 个 Python 文件(Flask 应用)
    • 2 个 HTML 模板 + 1 个 base 布局
    • 几行 CSS(甚至可以没有)
    • **0 行 JavaScript 业务逻辑**(除了加载 htmx.min.js)

    对比同样功能的 React SPA:至少 10 个文件、200+ 行 JS/TS 代码、状态管理、API 层、TypeScript 类型定义...

    HTMX 的进阶能力:不只是替换

    你以为 HTMX 只能做简单的 swap?它支持的能力远超你的预期:

    1. WebSocket 实时更新

    `html

    `

    2. SSE(Server-Sent Events)推送

    `html

    `

    3. 历史记录管理

    `html

    hx-get="/page/2"

    hx-push-url="true"

    hx-target="#content">

    第2页

    `

    加一个 hx-push-url="true",HTMX 自动帮你管理浏览器历史记录,前进后退按钮正常工作。这是很多"简易方案"踩的坑。

    4. 请求指示器

    `html

    `

    .htmx-indicator 类在请求期间自动显示,再也不需要手动写 loading 状态。

    架构视角:为什么这是正确的方向

    HTMX 不是一个玩具,它代表了分布式系统设计的某种回归:

    1. 关注点分离回归

    后端负责数据、业务逻辑、渲染模板——它本来就最擅长这些。前端只需要处理网络请求和局部 DOM 更新——HTMX 把这个职责降到最低。

    2. 渐进增强(Progressive Enhancement)

    即使 HTMX JS 加载失败或被 CSP 阻止,带有 hx- 属性的元素会优雅降级,表单依然可以通过传统方式提交。这是前端框架很少认真对待的问题。

    3. SEO 天生友好

    每个页面都是完整的 HTML,后端直接渲染,搜索引擎没有任何障碍。不需要 SSR、不需要预渲染、不需要 meta 标签同步。

    4. 极低的学习曲线

    团队里的后端 Python/Go/Java 开发者,不需要学习组件化、虚拟 DOM、状态管理,就能参与前端开发。技术债务大幅降低

    适用场景:不适合所有人

    说完优点也要诚实:HTMX 不是银弹。

    适合的场景:

    • 内部工具、管理系统(对性能要求不高,对开发速度要求高)
    • 内容为主的网站(CMS、企业网站)
    • 团队以后端为主,前端资源有限
    • 快速原型开发

    不太适合的场景:

    • 高度交互的复杂应用(看板、设计工具)
    • 需要复杂客户端状态(Figma、Notion 那种)
    • 离线优先的应用(PWA)
    • 对 bundle size 极度敏感(HTMX 本身 14kb gzipped,也不大)

    结论:工具应该匹配问题

    技术选型最大的错误是:用"最流行"而不是"最适合"。React/Vue 解决的是 SPA 时代的真实问题,但当 Web 标准(HTTP/HTML/CSS)本身已经进化到能更好解决这些问题时,我们是不是该重新评估?

    HTMX 不是一个倒退,而是一次拨乱反正。它提醒我们:最好的架构是让擅长的人做擅长的事,后端渲染 HTML、前端处理交互,本该如此

    下一次当你准备新建一个"前后端分离"的项目时,问自己一个问题:如果我只需要一个 CRUD 管理后台,真的需要动用 React 全家桶吗?

    也许,你只需要一个 Flask + HTMX。

    ---

    *附:本文完整代码示例可在 [htmx.org/examples](https://htmx.org/examples/) 找到。*