blog.dopana

Back

第3部:上級システム開発と実践Rust の第4回。WebAssembly(Wasm)は、Webブラウザやエッジ環境(Cloudflare Workersなど)において、ネイティブコードに近い速度で実行できるように設計されたバイナリ命令形式です。

Rustはガベージコレクタ(GC)を持たないため、バイナリサイズが極めて小さく、立ち上がりが高速であることから、WebAssemblyの最適な開発言語として広く認知されています。

graph TD
    A["Rustソースコード (.rs)"] --> B["wasm32-unknown-unknown ターゲットへコンパイル"]
    B --> C["wasm-bindgen & wasm-pack"]
    C --> D["WebAssemblyバイナリ (.wasm)"]
    C --> E["JS連携コード & TypeScript型定義 (.d.ts)"]
    D & E --> F["Webブラウザ / Cloudflare Workers / Node.js"]

10歳でもわかる説明(ELI5):自転車にジェットエンジンを載せる#

  • 通常のJavaScript:街中をスイスイ走れる小回りの利くシティサイクル。DOMの操作や画面の見た目を整えるのに最適です。しかし、重い荷物を運ぶような激しい計算(画像処理、動画編集、暗号計算、3D描画)では限界があります。
  • Rust + WebAssembly:自転車に小型ジェットエンジンを取り付けるようなものです。JavaScriptが合図を出すと、超重量級の計算処理をRust Wasmが一瞬で片付け、結果を滑らかに画面へ返します!

1. wasm-bindgen によるプロジェクト構成#

Cargo.toml にライブラリ設定を追加します:

Cargo.toml
[package]
name = "rust-wasm-demo"
version = "0.1.0"
edition = "2021"

[lib]
crate-type = ["cdylib"] # Wasm用の動的ライブラリを出力

[dependencies]
wasm-bindgen = "0.2"
toml

2. JavaScriptとRustの双方向連携#

#[wasm_bindgen] 属性を使用することで、JSとRust間のデータ受け渡しが自動生成されます:

3. wasm-pack によるビルド#

公式のパッケージングツール wasm-pack を使用します:

cargo install wasm-pack
wasm-pack build --target web
bash

生成される pkg/ フォルダの内容:

  • rust_wasm_demo_bg.wasm:最適化されたバイナリファイル
  • rust_wasm_demo.js:Wasm初期化用ラッパー
  • rust_wasm_demo.d.ts:TypeScript型定義ファイル

4. フロントエンドでの利用例#

5. 本番用バイナリサイズの最適化#

Webページの読み込み速度を高めるため、.wasm のファイルサイズを最小化します:

  1. Cargo.toml の最適化設定:
    [profile.release]
    opt-level = "z" # サイズ最優先の最適化
    lto = true
    codegen-units = 1
    panic = "abort"
    toml
  2. wasm-opt の活用:不要なコードを除去し、ファイルサイズをさらに20〜30%縮小します。

まとめ#

  • RustはGCを持たないため、軽量で起動が速いWebAssemblyバイナリを生成できます。
  • #[wasm_bindgen] により、JSとRust間の型変換が安全かつ自動的に行われます。
  • wasm-pack を使うことで、npmエコシステムやモダンフロントエンドへ簡単に統合できます。

参考文献#