WebAssemblyのファイルサイズを縮小
WebAssemblyのファイル(*.wasm)は、表示速度の面からファイルサイズがより小さいほうが望ましいです。本連載で利用してきた「wasm-pack build」コマンドは、デフォルトでリリース向けのビルドを行う(詳細は公式ドキュメント参照)ので、極端に余分なバイナリファイルは生成しませんが、設定次第でさらにファイルサイズを縮小できます。
最適化レベルの指定
Cargo.tomlファイルには、リスト12の通り、デフォルトで最適化レベルが指定されています。「profile.release」への指定はリリース向け(relase)ビルドへの指定を表すので、「wasm-pack build」でのビルド時に、この最適化レベルが反映されます。
[profile.release] opt-level = "s"
opt-lebelには、0(最適化なし)~3(すべての最適化を実施)、"s"(バイナリサイズを最適化)、"z"(さらにバイナリサイズを最適化)が指定できます。ただし、最適化の指定で逆にファイルサイズが大きくなる場合もあるため、実際にサイズを見ながら設定値を試す必要があります。今回のサンプルコード(p001-logging)では、opt-level = 3のときにバイナリファイルのファイルが最小になりました(詳細は後述)。
console_error_panic_hookを使わない
p001-loggingサンプルで紹介したconsole_error_panic_hookは、パニックの詳細を表示できる反面、ファイルサイズを増やす原因となります。十分に動作確認が終わったアプリではconsole_error_panic_hookを無効にすることでファイルサイズを縮小できます。Cargo.tomlの「features」をリスト13の通り変更することで、console_error_panic_hookを無効にできます(当然ですが、パニックの詳細はログ出力されなくなります)。
[features] default = [] # もともと指定されている"console_error_panic_hook"を削除する
アロケーターを変更
Rustで利用するアロケーター(メモリを確保する仕組み)を、WebAssemblyに最適化された「wee_alloc」に変更することでファイルサイズを縮小できます(それと引き換えに実行速度が落ちます)。Cargo.tomlの「features」をリスト14の通り変更します。
[features] default = ["wee_alloc"]
この設定により、lib.rsに記述されたリスト15の指定が有効となり、wee_allocが利用されるようになります。
#[cfg(feature = "wee_alloc")] // wee_allocがfeatureに設定されたときに有効 #[global_allocator] static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
ファイルサイズ縮小の実例
p001-loggingサンプルで、デフォルトから設定を変更していった場合のWebAssemblyファイルサイズを表1に示します。設定次第でファイルサイズを縮小できることがわかります。
No. | 条件 | WebAssemblyのファイルサイズ |
---|---|---|
1 | デフォルト状態 | 21,910バイト |
2 | No.1から最適化レベルを3に変更 | 21,152バイト |
3 | No.2からconsole_error_panic_hookを無効化 | 16,808バイト |
4 | No.3からwee_allocを有効化 | 10,853バイト |
完成したプログラムを世界に公開して再利用
Rust/WebAssemblyで作成したプログラムを世界に公開したいことがあるかもしれません。そうでなくても、自分でよく使うプログラムを公開しておけば、自分で再利用するときに便利です。以下では図5のサンプルで、Rust/WebAssemblyプログラムの公開と再利用について説明します。このサンプルはアップロードした画像をモノクロに変換するもので、詳細は第4回を参照してください。
このプロジェクトのWebAssemblyを公開してみましょう。まず、wasm-packコマンドをnpmのアカウントと連携させるため「wasm-pack login」コマンドを実行します。
コマンド実行時に表示されるURLを開くとログイン画面が表示されるので(図8)、npmのアカウントとパスワードでログインします。アカウントは無料で作成できます。
次に、「wasm-pack build」コマンドでWebAssemblyをビルド後、「wasm-pack publish」コマンドを実行すると、WebAssemblyがnpmに公開されます。ただし、サンプルコードでそのまま実行すると「p003-image-processor」という名前が使用済みで公開できないため、Cargo.tomlでパッケージ名を変更してから実行してください(リスト16)
[package] name = "p003-image-processor-xxxx" # ここを書き換えてパッケージ名を変更
公開されたパッケージは通常のnpmパッケージ同様プロジェクトに導入できます。p004-use-image-processorのサンプルコードでは、package.jsonにリスト17の通り記述して、npm上に存在するp003-image-processorパッケージを追加しています。
"dependencies": { "p003-image-processor": "^0.1.0" },
「npm install」コマンドでp003-image-processorパッケージを導入後、「npm run start」コマンドを実行すると、元のp003-image-processor同様に、図7の通り実行できます。
まとめ
本記事では、Rust/WebAssemblyのデバッグ時に必要なログ出力方法と、WebAssemblyのファイルサイズ縮小方法、パッケージ公開と利用方法を説明しました。各種ログや実行時間をコンソールに出力して、プログラムの動作状況を確認できます。WebAssemblyのサイズ縮小は、Webページの読み込み速度改善に役立ちます。作成したプログラムをパッケージとして公開することで、別なプロジェクトで部品として再利用できます。
本連載では今回まで、Rust言語を利用したWebAssemblyの実装について紹介してきました。最近のWebブラウザーではJavaScriptが高速で動作するようになりましたが、それでも速度が足りない、もっと最適化したいというときに、WebAssemblyは有力な選択肢です。フロントエンドプログラムの幅を広げるWebAssemblyの世界に、Rust言語を武器に挑戦してみてはいかがでしょうか。