DEV Community

Sendil Kumar
Sendil Kumar

Posted on • Edited on

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.

Liquid error: internal

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

Enter fullscreen mode Exit fullscreen mode

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 
Enter fullscreen mode Exit fullscreen mode

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. ❤️

Top comments (9)

Collapse
 
johnfound profile image
johnfound

I wonder, whether someone is trying to program in WebAssembly directly and what will be the size of the programs in this case.

Because, if we are talking about the CPU assembly language programming, it usually gives huge amount of size and speed improvement.

The program mentioned in the article is relatively simple. If imagine we want to implement it as a desktop application in Linux or Windows, my estimation is that it easily can be fit in less than 1KB and the main limitation factor will be the executable file format, not the code itself.

Collapse
 
elliot profile image
Elliot • Edited

Loving seeing the WebAssembly content on here.

I haven't used WebAssembly much, but this article gets me really excited about just how much performance you can squeeze out of it!

Collapse
 
sendilkumarn profile image
Sendil Kumar

Go for it... Let me know if you need help with anything :)

Collapse
 
gklijs profile image
Gerard Klijs

Any idea the sam program written in Rust would be similar in size? From the tutorial they used Binaryen and some couple of other tricks in the documentation to trim the size.

Collapse
 
sendilkumarn profile image
Sendil Kumar

Yeah. It is possible but I doubt we can achieve this much. I haven't played with it recently. Let me check what we can achieve there.

Collapse
 
sendilkumarn profile image
Sendil Kumar

Yeah it is awesome.

Collapse
 
stewartjarod profile image
Jarod Stewart

KB vs Kb

Collapse
 
sendilkumarn profile image
Sendil Kumar

typo 🙂

Collapse
 
matusbielik profile image
Matúš Bielik

So what's the main selling point of wasm? If compared to ja version,

Is the file of the compiled wasm smaller than a minified pure js script?

Is the execution speed noticeably faster?