Reduce your WebAssembly binaries 72% - from 56KB to 26KB to 16KB 🎉✨🦄
Tags: go, webassembly, webdev, javascript
Published: 2019-07-07 19:27:26

#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](https://medium.com/@addyosmani/the-cost-of-javascript-in-2018-7d8950fbb5d4) 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 :heart: with TinyGo. The WebAssembly binaries they produce are impressive and small :unicorn:.

[In the previous post](https://dev.to/sendilkumarn/create-dev-s-offline-page-with-tiny-go-and-webassembly-9n6), we have seen how we can reduce 50% of the binary size by removing `fmt`.

{% twitter 1147806626860208129 %}

Current binary size is `26KB` - check out this [commit](https://github.com/sendilkumarn/go-wasm/commit/f5837b0cee52f7598cff0da0a4f94770a29cb279)✨✨✨

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](https://tinygo.org/getting-started/). 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](https://webassembly.github.io/spec/core/binary/modules.html#sections).

The [Custom Section](https://webassembly.github.io/spec/core/binary/modules.html#binary-customsec) 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](https://github.com/WebAssembly/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](https://stackoverflow.com/questions/49205168/what-a-trap-instruction-does-in-operating-system) 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](https://github.com/sendilkumarn/go-wasm/blob/dev-board/)


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](https://twitter.com/sendilkumarn).

If you like this article, please leave a like or a comment. :heart: