提示:本网站现在为维护调试状态

WebAssembly 入门:Rust 编译 WASM + JS 调用

Choyeon
Choyeon
2026年9月1日 1 分钟阅读 643 阅读
479 字 1,424 字符 更新于 2026年11月8日
WebAssembly 入门:Rust 编译 WASM + JS 调用
目录

前端遇到图像/矩阵/密码学等 CPU 密集任务时,JS 性能成瓶颈。WebAssembly 让 Rust 代码编译为接近原生速度的字节码。

工具链与基础绑定

安装 wasm-pack 后,用 #[wasm_bindgen] 宏把 Rust 函数导出为 JS 可调用形式。复杂结构用 serde + serde_wasm_bindgen 序列化跨语言传递。

use wasm_bindgen::prelude::*;
use serde::{Serialize, Deserialize};
use web_sys::console;

#[derive(Serialize, Deserialize)]
pub struct MatrixResult { rows: usize, cols: usize, data: Vec<f64>, compute_ms: f64 }

#[wasm_bindgen(start)]
pub fn init() {
    console_error_panic_hook::set_once();
    console::log_1(&"[WASM] Matrix module loaded".into());
}

#[wasm_bindgen]
pub fn matrix_multiply(a_ptr: *mut f64, a_rows: usize, a_cols: usize, b_ptr: *mut f64, b_cols: usize) -> JsValue {
    use std::time::Instant;
    let t0 = Instant::now();
    let a = unsafe { std::slice::from_raw_parts(a_ptr, a_rows * a_cols) };
    let b = unsafe { std::slice::from_raw_parts(b_ptr, a_cols * b_cols) };
    let mut c = vec![0.0f64; a_rows * b_cols];
    for i in 0..a_rows {
        for k in 0..a_cols {
            let aik = a[i * a_cols + k];
            let rb = &b[k * b_cols..(k + 1) * b_cols];
            let rc = &mut c[i * b_cols..(i + 1) * b_cols];
            for j in 0..b_cols { rc[j] += aik * rb[j]; }
        }
    }
    let r = MatrixResult { rows: a_rows, cols: b_cols, data: c, compute_ms: t0.elapsed().as_secs_f64() * 1000.0 };
    serde_wasm_bindgen::to_value(&r).unwrap()
}

#[wasm_bindgen]
pub fn fibonacci_iter(n: u32) -> u64 {
    if n <= 1 { return n as u64; }
    let (mut prev, mut curr) = (0u64, 1u64);
    for _ in 2..=n { let next = prev.saturating_add(curr); prev = curr; curr = next; }
    curr
}

#[wasm_bindgen(js_name = "allocateFloat64Array")]
pub fn allocate_f64(len: usize) -> *mut f64 {
    let mut v = Vec::with_capacity(len);
    let p = v.as_mut_ptr();
    std::mem::forget(v);
    p
}

JS 调用与内存共享

WASM 内存是共享 ArrayBuffer,通过 TypedArray 视图直接读写比参数序列化快 10-100 倍。大数据时直接分配内存给 JS 端填充,再传指针和尺寸给 WASM。

对比项 纯 JS WASM (Rust) 加速倍数 适用场景
矩阵乘法 1024x1024 ~1800ms ~85ms ~21x 3D/游戏/AI推理
Fibonacci(n=40) ~980ms ~8ms ~120x 数学计算
SHA-256 1MB ~42ms ~6ms ~7x 密码学/校验

最佳实践

适合计算密集型循环,不要做 DOM 操作。优先 TypedArray 共享内存而非大对象参数,发布构建用 wasm-opt 优化体积。

X微博Telegram

本文作者

投票

你最希望 Rosetta 优先加入哪项功能?

社区投票(演示数据,可后台删除)

评论 (3)

0 / 3000
AI炼丹学徒
AI炼丹学徒2026年9月29日

补充一点:实际使用中如果遇到 MySQL 的 8 小时超时问题,可以在连接串里加 autoReconnect=true 参数,虽然官方不推荐但挺好用的。

画画的小鱼
画画的小鱼fishgallery.art2026年9月29日

哈哈,楼主的踩坑经历和我一模一样!我当时就是没注意到这个配置,排查了整整两天,看到这篇文章泪目了。

熬夜攻城狮
熬夜攻城狮nightowl.tech2026年9月28日

受益匪浅,感谢大佬分享!

相关文章

Rust 所有权与借用机制:彻底理解生命周期

Rust 所有权与借用机制:彻底理解生命周期

系统攻克 Rust 最独特概念:所有权规则、可变/不可变借用约束、引用生命周期标注。通过编译错误示例 + 修复方案,彻底掌握借用检查器思维方式,写出安全零抽象开销的系统代码。

1 分钟阅读
Linux 性能调优:perf_events + bpftrace + BCC

Linux 性能调优:perf_events + bpftrace + BCC

从 CPU、内存、IO、网络四个维度,使用 perf_events 采样堆栈、bpftrace 一行脚本追踪内核点、BCC 工具集 biolatency/offcputime,快速定位生产服务器性能瓶颈,附真实排查思路。

1 分钟阅读
TypeScript 高级类型体操

TypeScript 高级类型体操

TypeScript 的类型系统堪比一门完整的编程语言。本文系统讲解条件类型、映射类型、模板字面量类型、infer 推断、递归类型、分布式条件类型等高阶特性。配合 15+ 真实工具类型实现(DeepPartial、PathOf、PickByType、CamelCase 等),带你掌握 type-challenges 中级难度以上的解题思路。

1 分钟阅读
PostgreSQL 查询优化技巧

PostgreSQL 查询优化技巧

深入掌握 PostgreSQL 查询优化的核心方法:从 EXPLAIN ANALYZE 执行计划解读,到索引类型选择(B-tree/GIN/BRIN)、统计信息更新、连接策略调整、分区表设计,全方位提升数据库查询性能。

1 分钟阅读
Zero Trust 安全架构入门:永不信任,始终验证

Zero Trust 安全架构入门:永不信任,始终验证

零信任安全模型系统入门:以"永不信任,始终验证"为核心原则,打破传统边界防护(VPN=内部可信)的思维。从身份认证(MFA/SAML)、设备健康检查、最小权限 RBAC、微隔离 mTLS、持续信任评分到可观测审计链路的 6 大支柱详解,附落地实施路线。

1 分钟阅读
测试金字塔:单元/集成/E2E 测试比例与落地

测试金字塔:单元/集成/E2E 测试比例与落地

系统解析测试金字塔架构:从底层单元测试(大量快速、Mock 隔离依赖)、中层集成测试(服务/数据库/消息协作真实交互)、顶层 E2E 测试(真实用户路径少量精测)的推荐比例 70% / 20% / 10%,附项目覆盖率指标与落地实践。

1 分钟阅读