从代码库中移除 React.js 并采用 HTMX 实现 UI 交互 (2023)
Hacker News 摘要原标题:Removing React.js from the codebase and adapting Htmx for UI interactivity (2023)
Misago 论坛项目的负责人 rafalp 发起了一项关于从代码库中移除 React.js 并改用 HTMX 来实现 UI 交互的路线图讨论。
现状与存在的问题
目前 Misago 的运行方式是:用户请求页面后,Django 后端收集数据并渲染包含完整 HTML 和 JSON 数据的模板。此时页面由于禁用了表单,并没有交互性。随后 JavaScript 下载并运行,读取嵌入的 JSON 数据,将 Django 渲染的大部分 HTML 替换为来自 React.js 组件生成的 HTML。
这种方法存在以下严重问题:
• 重复实现:大量页面需要在 Django 模板和 React.js 组件中各实现一次。
• 开发体验差:定制 HTML 的用户会发现,他们修改了 Django 模板,但修改内容在页面上闪现一秒后就被 React.js 生成的内容替换了。
• API 负担:每个视图都需要 Django 模板、React.js 路由、API 接口和 JSON 序列化器。
• 性能损耗:用于 React.js 的 JSON 序列化会减慢响应生成速度。大量的 JavaScript 会降低性能,尤其是在旧款移动设备上。
• 国际化冗余:翻译信息在 Django 和 JavaScript 的翻译文件中重复存在,增加了下载体积。
• 插件开发困难:插件作者需要同时掌握 Django 和 React.js,且必须实现两套模板。
替代方案的选择
负责人考虑过两种方案:
1. 彻底舍弃 Django 视图和模板,只保留极简版本给搜索引擎爬虫,全身心投入 API 和纯 React.js 应用的开发。
2. 将 Django 简化为 API,配合 Next.js 或 Remix 等服务器端渲染框架。
但他认为,许多论坛软件依然坚持传统的服务器端渲染,仅在客户端使用少量 JavaScript 增强交互,这种方式并没有上述问题。论坛的交互通常是局部的,例如版务操作、订阅主题、写回复、看通知或投票。
引入 HTMX
HTMX 是一个体积很小的库,允许开发者将 HTML 的某些部分指定为动态岛屿,通过交互触发服务器返回的新 HTML 来进行局部替换。
• 实现原理:它类似于 20 年前的 jQuery 调用或 Rails 的 Turbolinks。它是声明式的,不需要编写专用的 JavaScript 或 React.js 代码。
• 优点:后端只需在收到来自 HTMX 的请求时,返回该局部的 HTML 片段而非整个页面。这消除了 JSON 序列化的需求,保持了架构的简单性。
路线图与实施计划
由于 admin 管理面板已经使用了可复用的 Django 视图且工作良好,负责人决定不将其迁移为单页面应用。从 React.js 迁移到 HTMX 将是一个长期过程,采取分步走的策略:
• 逐步替换:逐个发布版本来替换导航栏、主题列表、主题详情页和用户资料页等。
• 时间表:由于需要先完成插件系统、权限系统和新解析器的开发,HTMX 的大规模迁移预计在 2024 年底进行。届时还将同步更新到最新的 Bootstrap。
• 过渡期:在迁移过程中,部分页面可能既没有 React.js 也没有 HTMX,会变成纯粹的多页面应用,即点击链接或提交表单会导致全页刷新。但在点赞或投票等必须局部刷新的场景,会使用 AJAX 或 HTMX 占位。
优化成果记录
负责人分享了 Misago 0.39 版本的 JavaScript 文件体积,其中核心库和业务代码压缩前超过 1.2MB。在随后的更新中,迁移效果已经显现:
• 账户设置页:已完全由 Django 视图和 HTMX 实现,misago.js 的体积减少了约 37KB。
• 主题列表:已几乎从零重写,改用 Django 视图和 HTMX,misago.js 的体积进一步减少了 48KB。