bytecodealliance/javy を軽く調べた
この記事は 0df708ec7b455a4896481a4926eccb23fe6c6014 時点でのソースコードをもとに書いています。詳細は自分で確認してください。
背景
sqlc-gen-typescript が tsc + esbuild + javy を使って作られていてそこで javy の存在を知りました。
TypeScript で wasm のプラグインが簡単にかけるのはすごく便利ですが若干ビルドが遅いと思ったのが調査のきっかけです。
bytecodealliance/javy について
JavaScript を wasm にランタイムごと埋め込んで実行できるようにするツールでランタイムは QuickJS を用いています。
static linking と dynamic linking があって QuickJS を含まない形でも wasm が出力できるようですが今回は static linking のみを調査しました。
(QuickJS を含まない形ってどうやって実行するのだろうか?)
まず swc をライブラリとして使用して JavaScript のパースを行い、export 周りの情報を処理します。
QuickJS を内部で用いている javy_core (wasm として埋め込まれている) に JavaScript を入力として与え、wizer を用いて pre-initialize を行い QuickJS Bytecode 変換まで処理が進んだ wasm を作成します。
作られた wasm を wasm-opt で最適化して、ソースコードセクションに brotli で圧縮した JavaScript を入れて出力します。
なぜビルドが遅いと感じたのか
今回の入力は sqlc のプラグインで JavaScript が 8.5MB でした。
実行には不要なソースコードセクションの JavaScript の brotli での圧縮(最大レベル)に全体の80%である12秒かかっていました。
圧縮レベル | wasm のサイズ | 秒数 |
---|---|---|
0 | 80587250 | 0 |
5 | 73000152 | 0.5 |
8 | 72884233 | 0.8 |
11(最大) | 72671954 | 12 |
ソースコードを含まない | 71659880 | 0 |
圧縮レベルを変更することで速くなることがわかりましたが現時点では圧縮レベルは固定されていて設定で変更できないようになっていました。
圧縮レベルを変更できるようになるか、ソースコードを含まない設定ができるようになればよいなと思いました。
結論
圧縮はオフにできると嬉しいがそういうツールじゃないかも