ブログ一覧へ
tech 2026-03-28

なぜクラウド API より WebAssembly を選んだのか

なぜクラウド API より WebAssembly を選んだのか

ある夜遅く、私たちはクラウド請求書とレイテンシヒストグラムのスプレッドシートを見つめていました。トラフィックが急増するたびに、オートスケーリング、コールドスタート、たった 2 ページを結合するために本当に PDF を海の向こうへ送る必要があるのかについての会話が増えました。その夜、私たちは単純な問いを立てました:代わりにブラウザが重い仕事をできたとしたら?

アーキテクチャを変えた瞬間

Ai2Done は、生産性ツールが契約書、請求書、家族写真をサードパーティのサーバーに預けることを要求すべきではない、という信念から生まれました。クラウド API は強力ですが、永続的な依存関係を導入します:あなたのバイト列はマシンを離れ、コントロールできないネットワークを通り、決して監査することのないディスクに着地します。多くのワークフローではそれが許容範囲ですが、私たちのユーザーには受け入れがたいものでした。

WebAssembly は、サーバーで使うのと同じ言語である Go からコンパイルされた本物のコードを、ユーザーのタブ内で実行する信頼に足るパスを与えてくれました。ファイルをブラックボックスにアップロードする薄いクライアントをスケッチする代わりに、予測可能なパフォーマンスとサプライズ egress 料金なしで、ローカルで実行可能な可搬バイナリを配信できるのです。

なぜ「単に」JavaScript を使わないのか

UI とオーケストレーションには JavaScript を愛していますが、メガバイト単位の PDF ロジックや暗号を手書きの JS に移すことは、出荷が遅く、Go ツールチェーンと同期を保つのが難しくなったでしょう。WASM は実戦テスト済みのライブラリ(pdfcpu スタイルのパイプライン)を再利用し、スタック横断で型とテストを共有することを可能にします。ブラウザは書き換え先ではなく、ホストになります。

JS のミニマルなブリッジが .wasm モジュールを読み込み、ファイルハンドルと進捗コールバックを渡し、結果をレンダリングします。残りは Go に留まります:

// 概念的な形:WASM は薄い API をエクスポートし、本当の仕事は internal/tools に留まる。
func ProcessPDF(input []byte) ([]byte, error) {
    // 結合、分割、暗号化 — すべて決定論的、すべてローカル
    return merged, nil
}

得たもの

設計によるプライバシー。 処理が WASM 内で行われると、「あなたのファイルを処理する可能性がある」と言うプライバシーポリシーは必要なく、「できない」と言えます。バイト列がデバイスを離れないからです。これはマーケティングではなく、物理です。

重要な場所のレイテンシ。 バッチ操作では、ネットワークの往復が支配的になることがよくあります。ローカル WASM はその変数を完全に削除します。進捗バーは、誰かのリージョンのキュー深度ではなく、実際の CPU 作業を反映します。

コストの予測可能性。 私たちのインフラ請求書は、ユーザードキュメントのギガバイト数ではなく、サイトへのトラフィックに応じてスケールします。このアラインメントによって、すべての変換を計測する代わりに、製品品質に集中し続けられます。

正直に受け入れるトレードオフ

WASM はタダではありません。初期ダウンロードサイズが重要なので、Brotli で圧縮し、ツールごとに遅延読み込みし、タブクラッシュの代わりに親しみやすいメッセージを得られるよう、妥当なファイル制限を設定します。ブラウザのメモリ上限は現実です。それらを文書化し、進捗を表示することで、ユーザーはアプリが動作していること(フリーズではない)を知ります。

認証、検索インデックス、静的アセット配信など、サーバーに属するものには依然としてサーバーを使います。この分割は意図的です:識別と発見にはサーバー、変換にはクライアント。

今後の展望

クラウド API より WASM を選んだのはクラウドへの賭けではなく、ユーザーの主権への賭けでした。新しいツールを出荷するたびに、まずローカルで実行できるかを尋ねます。その規律が Ai2Done を高速、誠実、そして毎日依存している人々と調和した状態に保ちます。あなたがこの領域で構築しているなら、私たちの道がデフォルトのアップロード&処理パイプラインに疑問を持つ許可を与え、ブラウザにそれが信用されている以上のことをさせることを願います。