lightning-node-connect icon indicating copy to clipboard operation
lightning-node-connect copied to clipboard

build: investigate shrinking WASM blob size using tiny-go

Open Roasbeef opened this issue 3 years ago • 7 comments

Was brought up in this twitter thread: https://twitter.com/roasbeef/status/1486422025816064000

TinyGo is an alternate Go compiler that is intended for embedded systems, and support compiling to a WASM target: https://tinygo.org/docs/reference/usage/subcommands/#build.

Their overview page demonstrators shrinking a binary size by 99% just by instead compiling using the Tiny Go compiler. Certain Go language features aren't fully supported, so we may need to add some additional build tag layers to make it possible. So far, someone has identified that we'll need to build tag out the pprof import at the very least.

Roasbeef avatar Feb 21 '22 23:02 Roasbeef

runtime/trace package is incompatible. This breaks all the OpenTelemetry stuff https://github.com/tinygo-org/tinygo/issues/1997

kaloudis avatar Jul 14 '22 16:07 kaloudis

stdlib compatibility list here: https://tinygo.org/docs/reference/lang-support/stdlib/

I've assessed all the dependencies in LNC directly, and pulled in through vendor

issues with imports:

archive/tar crypto/ed25519 crypto/tls crypto/x509 encoding/xml expvar net/http net/http/httptest net/http/httptrace net/http/httputil net/http/pprof os/user

issues with tests:

bufio bytes compress/gzip context crypto crypto/aes crypto/cipher crypto/ecdsa crypto/elliptic crypto/hmac crypto/rsa crypto/subtle database/sql database/sql/driver encoding/asn1 encoding/base64 encoding/binary encoding/json encoding/pem errors flag fmt go/token hash/crc32 html/template image/color io io/ioutil log log/syslog math/big math/bits math/rand mime net/textproto net/url os/exec os/signal path/filepath regexp sort strconv strings sync/atomic syscall text/tabwriter

kaloudis avatar Jul 14 '22 17:07 kaloudis

Re OpenTelemetry, looks like it's just a dep brought in thru aperture:

⛰   go mod why go.opentelemetry.io/contrib
# go.opentelemetry.io/contrib
github.com/lightninglabs/lightning-node-connect/itest
github.com/lightninglabs/aperture
github.com/lightninglabs/aperture.test
go.etcd.io/etcd/server/v3/embed
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc
go.opentelemetry.io/contrib

In this case, it's only really required atm for the itests, so there might just need to add a build tag workaround.

Roasbeef avatar Jul 14 '22 22:07 Roasbeef

Not being able to import net/http seems like a pretty fundamental barrier.

However, I wonder if it's possible for us to take a multi-pronged approach here. With this hypothetical path, we'd actually have multiple wasm files, with us trying to pack as much into the tinygo compiled file as possible. I'm not sure if this is actually possible based on the way the project is architected however.

Roasbeef avatar Jul 14 '22 22:07 Roasbeef

In terms of shrinking things after the fact, looks like we might be able to use this wasm-opt tool to strip things down a bit more (namely the debug information): https://github.com/WebAssembly/binaryen#binaryen-optimizations.

Here's a blog post that shows an example near the end: https://www.fermyon.com/blog/optimizing-tinygo-wasm#Reducing%20More%20with%20Wasm-opt

Roasbeef avatar Jul 14 '22 22:07 Roasbeef

I tried gzip'ing locally, and got a pretty nice size reduction:

-rwxr-xr-x  1 roasbeef  staff    42M Jul 14 15:32 wasm-client.wasm
-rwxr-xr-x  1 roasbeef  staff   8.9M Jul 14 15:32 wasm-client.wasm.gz

Roasbeef avatar Jul 14 '22 22:07 Roasbeef

Are there any updates on this? I think it would be great to make more optimizations for file size, the current WASM file is sitting at 57.1mb. I was able to get it down to 49.6mb using wasm-opt which is an improvement but still not great.

secondl1ght avatar Jul 25 '23 15:07 secondl1ght