有段时间,我们在做一个基于 React 的后台系统,日常就是增删改查、数据管理。某天,产品提了个"常规需求":
"支持用户上传 CSV,导入数据表格,能筛选、搜索、排序。"
这玩意也太常见了,React + FileReader + PapaParse,三下五除二搞定,连分页优化都顺手加上。
上线当天,我还信心满满地和同事说:"这个功能稳得一批。"
结果当天晚上,客服群就炸了------
- "文件一上传就卡,鼠标直接不动了!"
- "筛选点半天没反应,感觉整个页面死了!"
- "在手机上直接崩溃,页面白的!"
我们赶紧上 devtools 查性能,一看就傻了眼:上传一个 8MB 的 CSV,页面直接卡住将近 10 秒。
根本原因?解析逻辑跑在 JS 主线程上。
PapaParse 开始解析 CSV,几十万行数据 + React render,JS 主线程像是一个搬砖工,突然被塞了三卡车的石头,累到头都抬不起来。
我们紧急加了 Web Worker,想把解析从主线程抽出去,结果发现:JS 自己就不快,换个房间干活也一样慢。
这就像你把一个跑 100 米 30 秒的人,从操场换到公园,他还是跑不过别人。
这就比如让你去NBA打球,没那个天赋你练一辈子也不可能。所以说天赋决定上限,努力决定下限。
我们突然意识到:这不是用不用 Worker 的问题,是 JS 这位"多面手"本来就不适合干这类密集型 CPU 工作。
为什么是 Rust?
说白了:JS 是灵活的,但在处理大规模字符串、数组、对象结构的时候,性能确实很吃力。特别是在浏览器里,它还得兼顾 UI 渲染和事件响应。
Rust 刚好反过来:
专长就是性能高、处理数据快
编译成 WebAssembly 后能在浏览器中跑
执行逻辑从主线程中"抽离出来",JS 不用再承担重负
更重要的是,它和现代前端构建工具(比如 Vite)配合也很好,接入没你想的那么复杂。
从零开始:Rust + WASM + React 接入流程
搭建 Rust 环境:
curl https://sh.rustup.rs -sSf | sh
cargo install wasm-pack
新建一个 CSV 解析项目:
wasm-pack new wasm-csv-parser
cd wasm-csv-parser
添加依赖:
[dependencies]
csv = "1"
wasm-bindgen = "0.2"
serde = { version = "1.0", features = ["derive"] }
serde_wasm_bindgen = "0.5"
核心代码只做一件事:解析 CSV 文本,变成二维数组,让前端拿来直接用:
#[wasm_bindgen]
pub fn parse_csv(content: &str) -> JsValue {
let mut rdr = ReaderBuilder::new()
.has_headers(true)
.from_reader(content.as_bytes());
let mut records = Vec::new();
for result in rdr.records() {
let record = result.unwrap();
let row = record.iter().map(|s| s.to_string()).collect::<Vec<_>>();
records.push(row);
}
to_value(&records).unwrap()
}
构建生成 .wasm 文件:
wasm-pack build --target web
接入 React:简单、丝滑
前端这边用的是 Vite 构建工具,配个插件,支持顶层 await 和 WASM 即可:
npm install vite-plugin-wasm vite-plugin-top-level-await
vite.config.ts 里加上插件:
plugins: [react(), wasm(), topLevelAwait()]
然后页面中调用 Rust 的解析函数:
import init, { parse_csv } from './wasm/pkg/wasm_csv_parser'
await init()
const result = parse_csv(content)
setData(result)
你没有看错,就是这么简单!
效果:不是优化,而是降维打击
我们做了对比测试:
| 技术方案 | 解析 8MB CSV 耗时 | 主线程卡顿 | UI 是否响应 |
|---|---|---|---|
| JS + PapaParse | 3.8 秒 | 高 | 卡 |
| Web Worker + JS | 2.7 秒 | 中 | 轻微卡 |
| Rust + WASM | 700ms | 低 | 不卡 |
甚至在手机端也表现稳定,不再崩溃。
更香的是,整个 .wasm 文件不到 200KB,加载飞快,不影响首屏性能。
几点经验总结
Rust + WASM 是目前前端解决"纯计算性能瓶颈"的一种非常实用的方案,用 Rust 写简单逻辑(比如解析、加密、压缩)并不难,尤其是不用多线程时。
React 项目中接入 WASM 没有想象中那么麻烦,Vite 的插件体系支持得很好,不必全项目重构,只替换关键逻辑,就能带来巨大收益
最后
我们不是为了尝鲜而用 Rust,是因为用户真实反馈页面卡顿,普通优化做不了,只能换思路。
Rust + WebAssembly 是一个解决特定前端问题的实际手段。而它的表现远超预期。
如果你也在用 React 做业务系统,有 CSV、Excel、图表、上传、数据计算等逻辑,可以试试用 Rust 来接管那些"又慢又卡"的部分。
只要用对了地方,Rust 是能在前端项目里发挥实打实的作用的。
后面我们会考虑把这个 CSV 解析模块做成 npm 包,方便更多人使用。也会继续尝试 Rust 做图片压缩、公式引擎、数据聚合,有空我再分享。
关注微信公众号:邹小邹-AI