はじめに
Cloudflare Workersはコード実行を世界330以上の拠点に分散させるエッジサーバーレスプラットフォームです。WebAssembly(Wasm)モジュールを統合することで、画像処理、暗号演算、動画エンコード、科学計算といったCPU負荷の高い処理をネイティブに近い速度で実行しつつ、エッジ配信の低レイテンシを維持できます。本記事ではRustやAssemblyScriptをWasmにコンパイルしWorkersにデプロイする方法と、パフォーマンスのトレードオフを解説します。
Cloudflare Workersのランタイム
WorkersはV8 Isolates技術を採用しており、リクエストごとに独立したJavaScript環境を提供しますが、事前にウォームアップされたisolateが再利用されます。
| 特徴 | 詳細 |
|---|---|
| 実行モデル | リクエストごとにシングルスレッド、isolateで並行処理 |
| コールドスタート | ~5 ms(V8スナップショットによる) |
| メモリ制限 | Workerあたり128 MB |
| CPU時間制限 | 30秒(無料プランは50 ms) |
| Wasmモジュールサイズ制限 | 10 MB(圧縮後) |
Wasmモジュールの統合方法
.wasmバイナリをESモジュールとしてWorkerスクリプトに直接インポートできます。
// wrangler.toml
// [wasm_modules]
// MODULE = "path/to/module.wasm"
// src/index.js
import wasmModule from '../path/to/module.wasm';
export default {
async fetch(request) {
const instance = await wasmModule();
const result = instance.exports.myFunction(42);
return new Response(`Result: ${result}`);
},
};
Wrangler v3以降ではwasm_modulesバインディングが自動的にインスタンス化を提供します。
RustからWasmへのコンパイル
Rust(wasm-pack)はWorkers向けWasmの最も人気のある言語です。
cargo new --lib my-rust-wasm
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
pub fn heavy_compute(input: u32) -> u32 {
(0..input).fold(0, |acc, i| acc + i * i)
}
wasm-pack build --target web
生成された.wasmをwrangler.tomlで参照します。
[wasm_modules]
RUST_MODULE = "pkg/my_rust_wasm_bg.wasm"
AssemblyScriptの場合
export function heavyCompute(n: u32): u32 {
let sum: u32 = 0;
for (let i: u32 = 0; i < n; i++) {
sum += i * i;
}
return sum;
}
AssemblyScriptはRustのツールチェーン不要でTypeScript開発者にとって親和性が高い選択肢です。
パフォーマンス比較
WasmはJavaScriptでは低速なCPUバウンド処理で顕著な高速化を発揮します。
| 処理 | JS (ms) | Wasm (ms) | 高速化 |
|---|---|---|---|
| SHA-256ハッシュ(1 MB) | ~45 | ~8 | 5.6倍 |
| 画像リサイズ(4K→HD) | ~120 | ~22 | 5.5倍 |
| Fibonacci(45) | ~8,500 | ~950 | 8.9倍 |
| JSONパース(2 MB) | ~15 | ~11 | 1.4倍 |
I/Oバウンドな処理(fetch、KV読み取り、API呼び出し)ではWasmの優位性はほとんどありません。
コールドスタートの考慮点
WorkersはV8 Isolateのプリウォームによりほぼゼロのコールドスタートを実現しています。ただしWasmコンパイル自体がコールドisolateでの最初のリクエストに**~200–500 µs**追加されます。V8はコンパイル済みWasmコードをキャッシュするため、同一isolateでの後続リクエストではこのオーバーヘッドは発生しません。
const instance = await wasmModule(); // トップレベルで一度だけインスタンス化
export default {
async fetch(request) {
return new Response(instance.exports.process(request.url));
},
};
Workersデータサービスとの連携
WasmモジュールからWorkers KVやR2にアクセスすることも可能です。
const instance = await wasmModule();
const value = await env.KV_NAMESPACE.get('config');
const result = instance.exports.process(value);
まとめ
Cloudflare WorkersとWebAssemblyの組み合わせは、エッジアプリケーションの可能性を大きく広げます。暗号処理、圧縮、画像変換、複雑なデータ変換などCPUバウンドな処理を、V8 Isolateのゼロコールドスタートモデルにより、低レイテンシかつグローバルに分散した環境で実行できます。バランスの取れたアーキテクチャとして、Workers + Wasmは今後ますます重要な選択肢となるでしょう。
