打开一个用 Misago 搭的论坛,浏览器要做两次同样的事。Django 先把整页 HTML 拼好,连帖子列表都塞进一份 JSON 一起吐给你。JS 下载完成后,React 读这份 JSON,把刚渲染出的 HTML 整块换掉。
Misago 维护者受够了这套双份渲染。项目计划分批把 React 移出代码库,改用 HTMX 做局部更新,不是一次性推翻重写,而是先啃掉部分页面,其余页面接受一段"点链接就刷新整页"的过渡期。
双份渲染,代价在哪
现在的路径是这样:请求进来,Django 视图渲染出几乎完整的 HTML,同一份数据顺手打包成 JSON 埋进页面。JS 加载完,React 把这块 HTML 整个换成组件版本。
代价很实在。几乎每个页面要写两遍模板,Django 模板一份,React 组件一份。路由、翻译文件(django.po 和 djangojs.po 各存一份)、插件扩展点,都要照顾两套。
维护者提到过一个真实的坑:有人改了 Django 模板,页面先闪一下改动,马上又被 React 覆盖回原样。他不知道自己还需要改另一份组件——这种"改了却没生效"的调试成本,比包体积数字更容易被低估。
对维护多插件生态的开源论坛项目来说,这类双头维护会随插件数量增加,不是一次性成本,是长期税。
HTMX 换的是什么,没换的是什么
HTMX 的做法是把页面上会变化的区域标成"孤岛"。交互发生时,浏览器只问服务端要这一小块新 HTML,换掉对应区域,其余部分不动。切换帖子分类,后端判断请求来自 HTMX,只返回帖子列表那一段,不用序列化 JSON,不用写专门的 React 组件。
这个思路不新。二十年前 jQuery $.get() 换局部内容,或者 Rails 的 Turbolinks,做的是同一件事,HTMX 只是换了个更声明式的写法。古人说"反者道之动",论坛这类产品绕回局部刷新,倒有点这个意思——走了一圈复杂架构,又回到了更朴素的路数。
迁移是分批推进的,不是一次切换:
| 阶段 | misago.js | gzip 后 |
|---|---|---|
| 迁移前 | 615KB | 124KB |
| 账户设置页迁移后 | 578KB | 107KB |
| 帖子列表页迁移后 | 530KB | 99KB |
| vendor.js(未变动) | 679KB | — |
vendor.js 的 679KB 基本没动,说明这件事离整体完成还远。维护者当时的计划是完整迁移排到 2024 年之后,管理后台不动,继续用 Django 通用视图。这是 2023 年的讨论材料,目前公开信息只能确认部分页面已经切换,没有证据说明整站迁移已经收尾。
过渡期里,部分页面既没了 React,也还没接上 HTMX,点链接、提交表单就老实刷新整页。只有点赞、投票这类刷新页面完全不能忍的交互,才专门保留异步处理。
这笔账谁该算,谁不用跟
这套思路对论坛类产品站得住。交互点状,数据大头在服务端,SPA 换来的"无刷新"体验,没盖住双份渲染、双份翻译、插件写两遍的维护成本。
但别把这事读成"HTMX 优于 React"的通用结论。一个需要复杂客户端状态、频繁跨页面数据联动的产品,比如在线文档编辑器、看板协作工具,HTMX 很难覆盖这类场景,SPA 该用还得用。Misago 做的是重新算一遍论坛这种产品的复杂度账,不是给所有前端架构判死刑。
包体积从 615KB 降到 530KB,gzip 后从 124KB 到 99KB,数字是真的,但不等于用户体验立刻变好。服务端响应速度、缓存策略、网络条件,才是决定加载体验的关键变量,这些材料里都没有实测数据,只能说目前还看不清。
对正在维护 Django、Rails 这类服务端渲染项目、又被 SPA 双份渲染和前端构建链拖累的团队,Misago 的路径值得参考,更适合先在低风险页面小范围试点,而不是照抄整站重写。对已经用 React 或 Vue 做复杂交互面板的团队,这篇材料不构成换栈理由。
接下来该盯的是三件事:vendor.js 的 679KB 什么时候真正下降,过渡期的整页刷新体验有没有引发用户抱怨,完整迁移是不是真按计划挤进了 2024 年之后。这几项目前都没有公开的后续确认。
论坛先把架构做重了一遍,又轻装绕回去。技术选型这件事,复杂度从来不是免费的,兜兜转转最后还是要照实结账。
