- turn on lto to reduce the size of the wasm blob.
lto = true in the
lto = true
This gives LLVM many more opportunities to inline and prune functions. Not only will it make the .wasm smaller, but it will also make it faster at runtime! The downside is that compilation will take longer.
- tell LLVM to optimize for size instead of speed.
LLVM's optimization passes are tuned to improve speed, not size, by default. We can change the goal to code size by modifying the
[profile.release] section in
Cargo.toml to this:
opt-level = 's'
Or, to even more aggressively optimize for size, at further potential speed costs:
opt-level = 'z'
Note that, surprisingly enough,
opt-level = "s" can sometimes result in smaller binaries than
opt-level = "z". Always measure!
- Use the
The Binaryen toolkit is a collection of WebAssembly-specific compiler tools. It goes much further than LLVM's WebAssembly backend does, and using its
wasm-opt tool to post-process a
.wasm binary generated by LLVM can often get another 15-20% savings on code size. It will often produce runtime speed ups at the same time!
# Optimize for size.
wasm-opt -Os -o output.wasm input.wasm
# Optimize aggressively for size.
wasm-opt -Oz -o output.wasm input.wasm
# Optimize for speed.
wasm-opt -O -o output.wasm input.wasm
# Optimize aggressively for speed.
wasm-opt -O3 -o output.wasm input.wasm
From my experience
wasm-opt is able to reduce a
node_runtime.compact.wasm from 4.3MB to 3.8 MB. Your mileage may vary.
$ du -sh ./target/release/wbuild/node-runtime/node_runtime.compact.wasm
$ wasm-opt -Oz -o output.wasm ./target/release/wbuild/node-runtime/node_runtime.compact.wasm
$ du -sh output.wasm
Edit: Sorry for lack of details on my first post attempt. I've added all the steps for you to follow and hope it works for you too.