Reduce your WebAssembly binaries 72% - from 56KB to 26KB to 16KB 🎉✨🦄

Every byte counts - Optimize them

Budgets are critical to the performance. It is very important to send down as less as possible. Check out more about the JavaScript's cost in this awesome article by Addy Osmani.

WebAssembly binaries depend on the underlying toolchain. It is important for every toolchain to optimize the binary as much as possible.

This is the reason why I fell in ❤️ with TinyGo. The WebAssembly binaries they produce are impressive and small 🦄.

In the previous post, we have seen how we can reduce 50% of the binary size by removing fmt .

Current binary size is 26KB - check out this commit✨✨✨

Now we will try to reduce the binary size further.

Use the latest dev branch

Currently, we have used TinyGo version 0.6.0 . Since it is actively in development. The current dev branch can shave off more bits. Let us use that.

Check the instructions about how to clone and build the project here. Once setup the TinyGo binary will be available inside the build folder.

Let us build it using this TinyGo binary.



../tinygo/build/tinygo build -o out/main.wasm -target wasm ./go/main.go

We removed 4KB , well it is not a huge improvement. But still every byte counts .

Current Binary size is 22KB .

Remove custom section

The WebAssembly binary is structured as sections. There are sections for memory, imports, exports, function definition and others. Check more about it here.

The Custom Section provides the metadata information. These metadata information are used for debugging. They are not required for the normal execution of the WebAssembly. We can remove them.

Note it is completely optional while debugging this section is useful. We can remove them in production.

We can use tools like WABT. With WABT we can convert the WebAssembly Module into Text Format and then back into WebAssembly Module. This will completely remove the custom section, and strip off a few extra bytes.

We removed another 4KB , well it is not a huge improvement again. But still every byte counts . Now the binary is 18KB .

Current Binary size is 18KB .

Remove Internal panics

The Tinygo provides a --panic option. With this option, we can choose the panic strategy. That is, this specifies compiled program should do when a panic occurs.

We can use the --panic trap option. This option will call the trap instruction in the platform in which it runs instead of throwing a panic.



../build/tinygo build -o out/main.wasm -target wasm -panic trap ./go/main.go

The resulting binary is 16KB. That is 2KB less.

Current Binary size is 16KB .

Thus we reduced the code another ~40% from 26KB to 16KB .

Thanks to Justin Clift

The repository is here

I hope this gives you a motivation to start your awesome WebAssembly journey. If you have any questions/suggestions/feel that I missed something feel free to add a comment.

You can follow me on Twitter.

If you like this article, please leave a like or a comment. ❤️