Shrinking .wasm Size

For .wasm binaries that we ship to clients over the network, such as our Gameof Life Web application, we want to keep an eye on code size. The smaller our.wasm is, the faster our page loads get, and the happier our users are.

How small can we get our Game of Life .wasm binary via build configuration?

Take a moment to review the build configuration options we can tweak to getsmaller .wasm codesizes.

With the default release build configuration (without debug symbols), ourWebAssembly binary is 29,410 bytes:

  1. $ wc -c pkg/wasm_game_of_life_bg.wasm
  2. 29410 pkg/wasm_game_of_life_bg.wasm

After enabling LTO, setting opt-level = "z", and running wasm-opt -Oz, theresulting .wasm binary shrinks to only 17,317 bytes:

  1. $ wc -c pkg/wasm_game_of_life_bg.wasm
  2. 17317 pkg/wasm_game_of_life_bg.wasm

And if we compress it with gzip (which nearly every HTTP server does) we getdown to a measly 9,045 bytes!

  1. $ gzip -9 < pkg/wasm_game_of_life_bg.wasm | wc -c
  2. 9045

Exercises

  • Use the wasm-snip toolto remove the panicking infrastructure functions from our Game of Life's.wasm binary. How many bytes does it save?

  • Build our Game of Life crate with and without wee_alloc as its globalallocator. Therustwasm/wasm-pack-template template that we cloned to start this projecthas a "wee_alloc" cargo feature that you can enable by adding it to thedefault key in the [features] section of wasm-game-of-life/Cargo.toml:

  1. [features]
  2. default = ["wee_alloc"]

How much size does using wee_alloc shave off of the .wasmbinary?

  • We only ever instantiate a single Universe, so rather than providing aconstructor, we can export operations that manipulate a single static mutglobal instance. If this global instance also uses the double bufferingtechnique discussed in earlier chapters, we can make those buffers also bestatic mut globals. This removes all dynamic allocation from our Game ofLife implementation, and we can make it a #![no_std] crate that doesn'tinclude an allocator. How much size was removed from the .wasm by completelyremoving the allocator dependency?