Nuxt3でwasmを実行する

computer program language text NuxtJS
Photo by Jorge Jesus on Pexels.com
この記事は約5分で読めます。

Webブラウザ上でネイティブコードを実行する仕組みにWebAssembly(wasm)という仕組みがあります。高度な画像処理などの計算をネイティブで高速に実行することでアプリケーションのパフォーマンスが向上しユーザー体験の向上が期待できます。

WebAssembly | MDN
WebAssembly は現代のウェブブラウザーで実行できる新しい種類のコードです。ネイティブに近いパフォーマンスで動作する、コンパクトなバイナリー形式の低レベルなアセンブリー風言語です。さらに、 C/C++、C# や Rust などの言語...

Nuxt3にはexperimental機能でありますがデフォルトでwasmをロードするための仕組みが用意されています。今回はこのwasmロード機能を使って、nuxtのプログラム内でwasmのプログラムを実行する方法を見ていきます。

環境

  • macOS Catalina 10.15.7
  • emcc 3.1.24
  • Nuxt 3.2.3

Nuxt3でのwasmのロード

Nuxt3(nitro)内部ではrollupのwasmプラグインを使用しています。拡張子がwasmのファイルのimport宣言を検出するとrollupによりwasmファイルのloadが実行されコードがtransformされます。

@rollup/plugin-wasm

rollupのplugin-wasmは、wasmのロードをへルパーコードに置換します。4つのtargetがあり、それぞれ以下のようになっています。

node nodejs想定、Base64からのデコード。
auto auto-inline、node、browserの混合(デフォルト)
auto-inline nodeとbrowserの混合
browser ブラウザ想定、fetchまたはBase64からのデコード。

参考 https://github.com/rollup/plugins/blob/master/packages/wasm/src/helper.ts

Nuxt3での設定

nuxt.config.tsには、rollupのplugin-wasmのオプションを指定することができます。nuxt3の公式の例ではboolean型のtrueを指定しています。trueはwasmロードを有効化するだけでrollupには無害な値となっています。

実際に指定できるオプションには以下があります。

sync

同期的にロードするwasmファイル
デフォルト:空の配列

maxFileSize

インライン生成の最大サイズ
デフォルト:14 * 1024

publicPath

maxFileSizeを超えた場合にwasmをコピーするファイル場所
デフォルト:空文字

targetEnv

wasm実行環境のターゲット
デフォルト:auto

fileName

ファイル名のフォーマット 
デフォルト:[hash][extname]

参考 https://github.com/rollup/plugins/tree/master/packages/wasm/#readme

Nuxt3でWASMを実行してみる

簡単な四則演算を実行するだけのプログラムを実行してみます。

wasmのビルド

まずは、Cのコードです。EMSCRIPTEN_KEEYALIVEマクロを指定するとwasmのexport対象と認識されます。

今回はemccコマンドでStandaloneモードでビルドします。

--no-entryがないと以下のようなエラーになります。メッセージを読むと、Standaloneモードのwasmでは--no-entryを使用するようにとあります。

生成されたwasmフィアるをテキスト表現形式で表示してみます。emscriptenの補助関数はなくStandaloneモードになっているようです。サイズは292byteです。

nuxt

続いてnuxt側のコードです。

configは以下のようにします。

クライアントは計算に使用する2値をクエリで渡してfetch関数でapiを呼びます。サーバapiではクライアントから受け取った値を元に計算を行ない結果をjsonで返します。以下のnuxtのサンプルプログラムと同様な形です。

参考:https://github.com/nuxt/framework/tree/main/examples/experimental/wasm

server/api/calc.ts

importでwasmファイルを呼んでいます。この結果はrollupによりtransformされます。

.nuxt/dev/index.mjsを見ると以下のようなコンパイル後のコードを確認できます。wasmプログラムはbase64でエンコードされているようです。

app.vue

app.vueでは、fetchでapiを呼び計算結果を受け取り表示します。

実際にページにアクセスしてみると、aとbの2値を用いた各計算結果を取得できるていることを確認できます。wasm機能は本執筆時点での公式ドキュメントを見るとexperimental機能となっていますが問題なく動作しているようです。

次はもう少し複雑な計算も試してみたいと思います。

参考リンク

コメント

タイトルとURLをコピーしました