µJS vs Turbo:相同的想法,不同的哲学
Source: Dev.to

Turbo(Hotwire 的一部分)和 µJS 解决的是同一个问题:让服务器渲染的网站在不重写前端 JavaScript 的情况下感觉更快。两者都拦截链接点击和表单提交,通过 AJAX 获取页面,并将内容注入到 DOM 中。
区别体现在 范围、体积和服务器需求 上。
大小
| Library | Size (min + gzip) |
|---|---|
| µJS | ~5 KB |
| Turbo | ~25 KB |
Turbo 的体积是 5 × 更大。对于一个主要工作是“获取页面并替换一些 HTML”的库来说,这是一条显著的差距。
构建步骤
Turbo 需要构建步骤——它以 npm 包的形式分发,旨在进行打包。
µJS 不需要:
mu.init();这对刻意避免 JavaScript 构建流水线的项目很重要(静态站点、PHP/Python/Ruby 应用,或任何添加 npm + 打包器会倒退的项目)。
Server‑side requirements
µJS 对你的服务器 没有任何要求。它发送标准的 HTTP 请求,并期待返回标准的 HTML。你现有的页面可以直接使用。
Turbo 有一些约定:
- Turbo Drive(基础导航)与 µJS 的工作方式相同。
- Turbo Frames 需要你的服务器返回特定的
<turbo-frame>元素。 - Turbo Streams(相当于 µJS 的 patch 模式)需要你的服务器返回用
<template>标签包裹内容的<turbo-stream>自定义元素。
采用 Turbo Streams 会改变服务器端的 HTML 输出。使用 Rails 和 Hotwire 生态系统时,辅助函数会为你处理这些;使用其他后端时,则需要你自行实现。
多片段更新:补丁模式 vs Turbo Streams
两个库都可以在单个响应中更新页面的多个部分。语法本身就说明了区别。
µJS – 补丁模式
服务器返回纯 HTML。每个片段都带有 mu-patch-target 和 mu-patch-mode 属性:
<div mu-patch-target="article" mu-patch-mode="replace">
<h2>Great article!</h2>
</div>
<div mu-patch-target="comments">
<p>14 comments</p>
</div>
<form mu-patch-target="comment-form">
<button type="submit">Submit</button>
</form>Turbo Streams
每个片段必须包裹在 <turbo-stream> / <template> 中:
<turbo-stream action="replace" target="article">
<template>
<h2>Great article!</h2>
</template>
</turbo-stream>
<turbo-stream action="append" target="comments">
<template>
<p>14 comments</p>
</template>
</turbo-stream>
<turbo-stream action="replace" target="comment-form">
<template>
<form>
<button type="submit">Submit</button>
</form>
</template>
</turbo-stream>使用 µJS 时,片段 本身就是 内容。 使用 Turbo 时,每个片段都需要一个包装结构。µJS 的做法更少样板代码,HTML 可以直接阅读。
另一个实用的优势:µJS 的 mu-patch-target 属性在首次页面加载时会被忽略,所以你可以在普通页面模板和补丁响应中使用完全相同的 HTML 片段。
HTTP 方法
| 特性 | Turbo | µJS |
|---|---|---|
| 支持的方法 | GET, POST | GET, POST, PUT, PATCH, DELETE |
| 如何使用额外动词 | 隐藏的 _method 字段或服务器端约定 | mu-method 属性用于链接、按钮和表单 |
<a href="/posts/5" mu-method="delete">Delete</a>
<form action="/api/publish/5" mu-method="patch">
<button type="submit">Publish</button>
</form>Turbo 对 PUT/PATCH/DELETE 的原生支持缺失,需要采用变通方案,而 µJS 则开箱即用地支持这些方法。
触发器和轮询
Turbo 只处理链接和表单。
µJS 添加了 mu-trigger,让 任何元素 能在 任何事件 上发起 fetch:
<button mu-trigger="click" mu-url="/refresh" mu-poll="5000">
Refresh every 5 seconds
</button>实时:服务器发送事件(SSE)
两个库都支持 SSE。
- µJS 内置支持,并复用相同的 patch 语法:
<div mu-patch-target="notifications" mu-patch-mode="append">
<!-- Server will push <div mu-patch-target="notifications">…</div> fragments -->
</div>服务器会推送带有 mu-patch-target 属性的标准 HTML 片段——与普通 patch 响应的格式相同。无需学习新东西。
- Turbo Streams 也可以通过 SSE 传输,但仍需使用
<turbo-stream>/<template>格式,服务器必须生成该结构。
TL;DR
| 方面 | µJS | Turbo (Hotwire) |
|---|---|---|
| 大小 | ~5 KB | ~25 KB |
| 构建步骤 | 不需要打包工具 | 需要 npm + 打包工具 |
| 服务器要求 | 无(普通 HTML 可工作) | 需要 <turbo-frame> / <turbo-stream> 以实现高级功能 |
| 补丁语法 | 使用 mu-patch-* 属性的普通 HTML | 包裹的 <turbo-stream> 元素 |
| HTTP 动词 | GET、POST、PUT、PATCH、DELETE | GET、POST(其他需要变通) |
| 触发器 | 在任何事件上使用 mu-trigger,轮询,防抖 | 仅链接和表单 |
| SSE 支持 | 内置,使用相同的补丁格式 | 支持,但使用 Turbo 特定标记 |
如果你想要一个 体积小、零配置、即插即用、能够兼容任何后端的方案,µJS 显然是首选。如果你已经深耕于 Rails/Hotwire 生态,并且需要它提供的更丰富的功能集,Turbo 可能更适合。
当 Turbo 更有意义时
Turbo 是正确的选择,如果:
- 你在 Rails / Hotwire 生态系统 中——集成深入,助手成熟,社区庞大。
- 你需要 Turbo Native 来开发 iOS/Android 应用。
- 你的团队已经熟悉 Turbo 的约定。
在 Rails 生态系统之外,Turbo 的约定会成为额外负担,而没有生态系统的好处。
摘要
| 功能 | µJS | Turbo |
|---|---|---|
| 大小 | ~5 KB | ~25 KB |
| 构建步骤 | 无 | 必需 |
| 需要的服务器更改 | 否 | 用于 Frames 和 Streams |
| 多片段更新 | 补丁模式(纯 HTML) | Turbo Streams(<turbo-stream>) |
| HTTP 方法 | GET/POST/PUT/PATCH/DELETE | GET/POST |
| 任意事件触发 | 是 | 否 |
| 防抖 / 轮询 | 内置 | 否 |
| SSE | 内置 | 内置 |
| Rails 生态系统 | 否 | 是 |
µJS 是一个专注的库:直接引入,调用 mu.init(),你的站点即可获得无需服务器更改的 AJAX 导航。如果需要更多功能,属性已经就绪;如果不需要,就无需为它们付费。
- Live playground — 交互式测试每个功能
- 完整对比:µJS vs Turbo vs htmx
- GitHub
npm install @digicreon/mujs