How small can TinyGo squeeze down WebAssembly?
Since we covered TinyGo last year, it has expanded its reach and seen several updates. This Go compiler for microcontrollers, modern web browsers, and command-line tools also can compile Go to WebAssembly to create browser-based apps. How small can TinyGo squeeze down WebAssembly and what drawbacks and limitations does it have?
TinyGo is a Go compiler for small places, including microcontrollers, modern web browsers, and command-line tools. It can also compile Go to WebAssembly (WASM) in order to create browser-based apps. So, just how small can you squeeze a gopher down?
When we first covered TinyGo last year, the project did not yet support WASM for browsers. Now, let’s take a look at how this project has grown, what changes it has made, and what developers are doing with the teeny-tiny Golang tool.
The current project release is version 0.60, updated on May 29, 2019. This release added some portability improvements to the command line, enhancements to help improve code quality, and fixed some bugs.
TinyGo has expanded its range and now supports 14 boards:
- Adafruit Circuit Playground Express
- Adafruit Feather MO
- Adafruit ItsyBitsy MO
- Adafruit Trinket MO
- Arduino Uno
- BBC micro:bit
- STM32F4 Discovery
- Phytec reel board
Squeezing down WebAssembly with TinyGo
Developer Sendil Kumar N has been running a series of regarding WASM performance optimizations using TinyGo. How much can you squeeze out of WebAssembly?
— sendilkumarn (@sendilkumarn) July 7, 2019
With the help of TinyGo, he has been able to reduce WebAssembly binaries by 72%.
According to his blog, he has achieved this reduction from 56kB, to 26 kB, all the way down to 16kB.
Some of the previously discussed drawbacks still remain, however. Most notably, TinyGo does not support garbage collection on a majority of microcontrollers.
From the documentation:
While not directly a language feature (the Go spec doesn’t mention it), garbage collection is important for most Go programs to make sure their memory usage stays in reasonable bounds.
Garbage collection is currently only supported on ARM microcontrollers (Cortex-M). For this platform, a simple conservative mark-sweep collector has been implemented. Other platforms will just allocate memory without ever freeing it.
Careful design may avoid memory allocations in main loops. You may want to compile with
-gc=noneand look at link errors to find out where allocations happen: the compiler inserts calls to
runtime.allocto allocate memory. For more information, see heap allocation.
Because of this GC limitation, WebAssembly projects made with TinyGo may face some memory usage hurdles, no matter how small they are.
Support for goroutines is still also considered experimental in the current build of TinyGo. The doc states, “simple programs usually work”.