写了八年 React Native,今天发现「真正的全栈」根本不是那么回事——Dioxus 把这件事彻底变了
写前端项目最烦的从来不是写代码,是项目跑起来之后还要配一整套完全不同的东西——React 写前端,Node.js 写后端,Swift/Kotlin 写 App,每次换层都要重新熟悉一套工具链。Flutter 试图解决这个问题,但它本质上是另一套DSL,团队里必须有人专门学它。
今天把这件事彻底变了的是 Dioxus——一个用 Rust 写的跨平台 UI 框架,一套 Rust 代码可以同时跑在 web、桌面(Windows/macOS/Linux)、手机(iOS/Android)上。bundler 内置,打包出来 web 应用 50kb 起,桌面/移动应用 5mb 起。
React 想解决但没解决的事,Dioxus 用 Rust 解决
React 的 virtual DOM 是一个妥协方案。JavaScript 没有内存所有权的概念,所以 React 选择了在运行时做 diff——每次状态变更都要遍历整个虚拟树,算出最小变更,再批量应用到真实 DOM。这个过程消耗的是运行时 CPU 和 GC 压力。
Rust 没有这个限制。Dioxus 的响应式系统直接跑在 Rust 的 ownership 模型上,不需要 virtual DOM 做中转。当状态变更时,Dioxus 知道哪些节点实际依赖这个状态,不需要 diff,直接精准更新。架构上就比 React 高了一截。
// Dioxus 的响应式状态——没有 virtual DOM,没有 diff
let mut count = use_signal(|| 0);
rsx! {
button { onclick: move |_| count += 1, "Up high!" }
}
对比 React Native 的架构:JavaScriptCore Bridge 要做两件事——把 JS 侧的 UI 描述序列化传到 native 侧,再把 native 侧的事件回调传回 JS 侧。每次交互都是一次跨语言序列化。React Native 新架构(Fabric + TurboModules)在这个方向上修了三年,JSI 替换了 Bridge,但序列化问题始终没有完全消除。
Dioxus 没有这个问题。Rust 代码直接编译到目标平台,没有中间层的序列化开销,也就没有 GC 压力,没有跨语言调用的延迟。
一套代码怎么跑四个平台
Dioxus 的跨平台不是写一套代码然后用 WebView 套壳,而是每个平台都有原生渲染路径。Web 端编译到 WASM,桌面端通过 webview 渲染,移动端同样通过原生组件树渲染。
fn app(cx: Scope) -> Element {
let mut count = use_signal(|| 0);
rsx! {
h1 { "High-Five counter: {count}" }
button { onclick: move |_| count += 1, "Up high!" }
button { onclick: move |_| count -= 1, "Down low!" }
}
}
这段代码在浏览器里跑就是 WASM 渲染,在 macOS 上跑就是 NSView,在 iOS 上跑就是 UIView,样式和行为完全一致。
全栈部分用的是 Server Functions——在 Rust 函数前加一个宏,这个函数就同时是服务端 API 和客户端调用端点,参数和返回值直接序列化 Rust 类型,不需要写 REST 接口,不需要写 TypeScript 类型绑定。
#[server]
async fn get_user(id: u64) -> Result<User, ServerFnError> {
db.get_user(id).await
}
// 客户端直接调用,像本地函数一样
let user = get_user(42).await;
开发体验才是杀手锏
Dioxus 内置的 dx serve 做了两件对前端工程师来说非常陌生,但对 Rust 工程师来说非常自然的事。
第一件事是 Subsecond Hot-Patching。修改 Rust 代码后,页面在亚秒级时间内更新,不需要刷新,不需要重新构建。更重要的是,状态保留——页面的当前数据不会因为代码更新而丢失,这是 HMR 完全做不到的事。
第二件事是 Asset Hot-Reloading。CSS 和静态资源变更会自动同步,不需要重新编译 Rust 代码,不需要重启开发服务器。
这两件事加在一起,Dioxus 的开发体验实际上比大多数前端框架更接近「本地 App 开发」的所见即所得。
数字上的优势是真实的
React Native 的 debug 包体积通常在 20MB 以上,iOS release 包 10MB 起跳,加上 JS bundle 实际加载时间,综合来看首屏体验始终是 RN 的痛点。
Dioxus 的 web 应用基准在 50kb(gzip),因为 Rust → WASM 编译产物是二进制的机器码,不需要运行时解释器。桌面/移动应用 5mb 起,这个数字对原生应用来说是正常的,对 JavaScript 跨端框架来说是不可思议的。
真实落地路径
Dioxus 目前生态比 React 年轻,主要社区资源集中在 GitHub 和 Discord,npm 生态里没有 React 那样大量的现成组件。以下几个场景是当前最适合切入的:
工具类应用。 需要高性能渲染,不需要复杂运营 UI 的工具类产品——Dashboard、数据可视化、编辑器——Dioxus 的性能优势在这些场景最容易体现。
对包体积敏感的产品。 C端移动应用对下载大小敏感,50kb vs 20MB 的差距在弱网环境下是决定性的。
Rust 团队的全栈需求。 后端用 Axum,全栈类型共享,前端用 Dioxus,一个语言覆盖完整链路,团队知识复用率最高。
如果你正在用 React,现在换过去成本太高。但如果你在规划一个新项目,或者团队有 Rust 能力,Dioxus 值得放进选型评估里——不是因为它比 React 更好用,而是因为它用一种完全不同的思路解决了 React Native 想解决但没解决好的那个问题。
下一步:亲自跑一遍
安装 Dioxus CLI:cargo install dioxus-cli,然后 dx create my-app 起一个项目,dx serve 跑起来。从创建一个计数器开始,感受一下 subsecond hot-patch 和 signals 状态管理的实际体验,这是读任何文章都替代不了的。
评论区
登录后可评论。