loading...

Reduce your WebAssembly binaries 72% - from 56KB to 26KB to 16KB ๐ŸŽ‰โœจ๐Ÿฆ„

sendilkumarn profile image Sendil Kumar N Updated on ใƒป3 min read

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. โค๏ธ

Posted on by:

sendilkumarn profile

Sendil Kumar N

@sendilkumarn

An explorer wandering in the land of programs. I am passionate about Open Source. "Docendo discimus"

Discussion

markdown guide
 

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.

 

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.

 

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.

 

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!

 

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

 

Thank you, very useful tips! TinyGo is cool, WASM output was 1.5M, now 66K