Skip to content

Guide on writing frontend apps in Go

Notifications You must be signed in to change notification settings

orsinium-labs/golang-wasm

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

8 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Go and WebAssembly

The repostitory contains the source code for my talk about compiling Go applications into WebAssembly (wasm) and how WebAssembly works.

Check out SLIDES from the talk.

Wasm internals

The section covers how wasm work internally. It is based on the A Talk Near the Future of Python screencast by David Beazley, and you should watch it. You can find in beazley directory the code from his screencast cleaned up, actualized, and reformatted by me.

To run the code:

  1. Install numpy and pygame.
  2. Download program.wasm and place it into beazley directory.
  3. Run python3 ./beazley/rocket.py

Exercise: Try changing the implementation of sin and cos functions so that sin returns cosines, and cos returns sines. How does it affect the program?

Hello world

To run this and all other examples, you'll need task installed. Also, you'll need the Go compiler. Preferrably, the latest version.

The source code for this section is available in hello directory.

  1. Run task build -- ./hello to produce the wasm binary and bootstrap code. You can find the output inside frontend directory.
  2. Run task serve to serve the content of frontend directory. Do it for all other steps too to see the result. Or just leave the server running from now on.
  3. Open localhost:1337. You should see a blank page.
  4. Open Chrome DevTools (press F12). Switch to the "Console" tab. You should see the "oh hi mark" output.

Exercise: Try replacing println by fmt.Println. How does it affect the binary size?

Calling JS from Go

The source code for this section is available in js directory. Compile and run it in the same way as you did in the previous section, just use task build -- ./js to build it.

Exercise: Replace window.Get("document") by window.Get("nope"). What do you see in Chrome Console?

Using GWeb

GWeb is a type-safe wrapper around Web API (JS calls). The sections shows a basic example of using it. You cna fid the source code for the section in gweb directory. Do the same steps as before to compile and run it.

You can find more examples at gweb.orsinium.dev.

Exercise: Make the page to show the current time. What time is it? When does it get updated?

Reducing the binary size using TinyGo

For this section you need to install TinyGo. Try running task install:tinygo, it might work. If it doesn't, just follow the official installation instructions.

  1. Compile the code from the previous section using TinyGo: task tiny_build -- ./gweb. Check if it works. Note the new size of the binary. On my machine, it dropped from 1.6M to 198K.
  2. Compile the same code without the scheduler: task tiny_build -- -scheduler=none ./gweb. Check if it works. Note the new size of the binary. On my machine, it's now 152K.
  3. Now, compile the first example without scheduler and with leaky GC (allocates but never frees): task tiny_build -- -scheduler=none -gc=leaking ./hello. Check if it works. What's the new size? On my machine, it dropped from 1.2M to 29K.

Exercise: Try building with -gc=none option. What's the size? Does it work?

Reducing the binary size using Binaryen

For this section, you'll need binaryen. Try installing it using task install:binaryen. If it doesn't work, manually download the latest release for your OS from Github releases.

  1. Build any of the examples from previous sections. For example, build gweb example using tinygo: task tiny_build -- -scheduler=none ./gweb.
  2. Run task optimize. Check if it works. Note the new binary size.

On my machine, the size of hello (with leaking GC) drops from 29K to 25K and the size of gweb drops from 100K to 89K.

WASI

The section covers compiling system applications into WASM with WASI system interface using TinyGo. To run the wasm binary from the terminal you need to install wasmtime. Try running task install:wasmtime. If it doesn't work, follow the official installation guide.

  1. Build the binary: task wasi:build
  2. Run it with wasmtine: task wasi:run

Exercise: Build the same hello example targeting wasm and wasi. Does the file size differ?

Further reading

  1. WebAssembly guides on MDN
  2. GWeb documentation
  3. AssemblyScript language