
Hands-on WebAssembly - progapandist
https://evilmartians.com/chronicles/hands-on-webassembly-try-the-basics
======
donatj
Most of my early excitement for WASM circled around “Hey, I can finally use a
decent language on the web” but since then I have grown to love TypeScript, so
a lot of that early excitement has been tempered.

I have done a number of experiments with Go’s WASM target, one of the earliest
and silliest porting Go’s “Otto” JavaScript runtime to WASM, so you can much
less efficiently run ES3 JavaScript in a browser.

I have also been working on porting a number of tools I currently have that
run server side with web frontends to pure WASM. I have had mixed success here
however and have found interacting with web elements and JavaScript from Go an
awkward, non statically validated, frustrating experience of trial-and-error
that somewhat undermines the joy of a statically typed language. On top of
everything, Go’s .wasm files are frustratingly large, “Hello World” starting
at 1mb and growing quickly from there.

All that said though, it is pretty magical seeing something written as a CLI
tool running in a browser with minimal changes.

~~~
the_duke
Go has to embed it's runtime and GC into builds, so build size and performance
will take a hit here. Same goes for most popular languages.

For me Rust offers the best WASM experience and tooling at the moment.

Rust has no GC and (almost) no runtime.

It also has official wasm build target support out of the box, including
generating Typescript definitions for Rust types.

The ecosystem is somewhat well-developed:

* wasm-bindgen for general interop in both directions

* js-sys / web-sys for (low-level) type-safe and surprisingly efficient browser API bindings

* wasm-bindgen-futures for easy Promise <-> Future interop

* wasm-pack for easy building

* ...

Getting the code size low is still a challenge though.

A Rust implementation of the Krausest frontend framework benchmark takes a top
4 spot [1]. Despite this benchmark not favouring wasm at all since it requires
little computation and mostly does FFI calls.

(ps: C++ is in a decent state as well)

[1] [https://rawgit.com/krausest/js-framework-
benchmark/master/we...](https://rawgit.com/krausest/js-framework-
benchmark/master/webdriver-ts-results/table.html)

~~~
pansa2
> C++ is in a decent state as well

I’d still choose Go or Rust over C++, though, because they’re memory-safe.
This recent discussion shows that’s still important in the context of
WebAssembly:
[https://news.ycombinator.com/item?id=24216764](https://news.ycombinator.com/item?id=24216764)

~~~
stjohnswarts
Modern C++ has a lot of memory safe operations if you use them (smart
pointers, atomics, actually using RAII properly and universally), although I'm
not sure how much overhead they might add to a wasm blob. Rust seems almost
perfect for it though, but no reason to discourage C++ people; it can be a
relatively modern language if you let it.

~~~
pjmlp
As someone that loves still having C++ on the toolbox, that is unfortunately
only true if you have 100% control over the source code and have all team on
modern C++ mindset.

------
zaarn
Fun fact: The new MS Flight Simulator 2020 uses WebAssembly to run the
software for the aircrafts in game. You can check the release notes, where
they do detail that webassembly is used for the SDK as well.

The intention is likely that if the onboard computer emulation crashes (which
it sometimes does) you can simulate the actual onboard computer restarting
without it taking down the game.

~~~
AnIdiotOnTheNet
> The intention is likely that if the onboard computer emulation crashes
> (which it sometimes does) you can simulate the actual onboard computer
> restarting without it taking down the game.

That doesn't really make any sense to me as a motivation. The vast majority of
ways they could have chosen to simulate the onboard computer would have that
quality. I would guess they chose WASM because they expect a lot of third-
party expansion and it provides a VM that can be targeted by almost any
language.

~~~
zaarn
Well, also yes, the side effect being that third party OBC's won't crash your
game if they go down.

And I would point out I've gotten the OBC in the default plane models to crash
a few times, they either get stuck in some undefined state or go black and
recover after a few seconds. It's rather interesting to observe.

------
vanderZwan
What holds me back from using WebAssembly is that it doesn't seem to provide
any performance benefit for small functions. Well, not _yet_ , I hope, because
I really like the idea of WASM.

For example, last week me and a few other users on Observable have been
experimenting with various JS ports of one particular permuted congruential
random number generator. Using assemblyscript I managed to write a decent-
enough WASM version, and it's _slower_ than implementing 64 bit arithmetic
with four 32 bit numbers, which involves a _lot_ more multiplications and
additions:

[https://observablehq.com/d/ce811886e1071d69](https://observablehq.com/d/ce811886e1071d69)

There are two possible explanations: either 64 bit integer arithmetic is still
really slow in WASM, or the call overhead is really, really significant.

This fits my earlier experience with trying to implement fast log
approximation functions for data-viz purposes (since the rounding errors would
not be visible at sub-pixel levels). They weren't much faster than the proper
Math.log function (whereas in pure C or C++ that difference would be much
larger).

I suspect that if this call overhead were reduced, it would be much easier to
gradually add more WASM to a Web App and reap the benefits of it.

~~~
saagarjha
Calling a short function is generally a poor idea, to be honest. You want
significant execution time on either side of the bridge, not constant boundary
crossing.

~~~
vanderZwan
The thing is that I had expectations of _why_ the boundary crossing was so
slow. I expected a no-heap WASM function that returns a simple value to be
pretty fast, but as the other comment points out the "boundary" in this case
might not be the WASM/JS boundary so much as the inability to inline WASM.

------
qppo
I'm just excited that I'll be able to write app extension APIs defined in C
and host them in a wasm runtime that doesn't have to run in a different
process to keep those extensions on their best behavior and not crash the app
when they segfault.

Not 100% sure if that's possible with WASM runtimes now or if it's faster (IPC
can be quite fast) but that's my hope.

------
mamcx
I hope some of the extensions for WASM land like
[https://github.com/bytecodealliance/wasmtime/issues/677](https://github.com/bytecodealliance/wasmtime/issues/677).
I take a look for build an interpreter to run fully on it, but still is
required to have a host that understand fully the types so is not much time
saving.

------
secondWave12
WebAssembly in the browser didn't have its breakthrough so far and probably
will never have. The problems WA tries to solve are no big problems, if
problems at all:

\- Typescript is an excellent language.

\- Performance of Javascript is for 99% of all the websites more than good
enough.

\- New frameworks like Svelte are much more mobile friendly in terms of
computational overhead or time to first render.

Also, work on WA has pretty much stalled.

~~~
k__
You can compile languages like C/C++ and Rust to it. Sometimes this gives a
performance boost, but most of the time it gives you just more uniform
performance behavior.

Then you can compile stuff like Java or C# to it, but end up with huge runtime
bundles. But you get much of the C# behavior from TypeScript without the huge
runtime, because it compiles directly to JavaScript.

~~~
wtetzner
It also allows you to run existing code in the browser, without having to do a
rewrite.

~~~
stjohnswarts
This seems like the biggest advantage to me. Not everyone wants to rewrite and
debug their several thousands of line rust/c++ program into typescript.

------
runawaybottle
Quite frankly, I need to see a reason why one would use WASM. Figma is a fully
justified implementation.

If you don’t like JavaScript, like get over yourself already. Enough is
enough.

It’s a a simple language, you will still have to deal with browser apis and UI
development patterns no matter what language you pick, and no, type checking
isn’t going to magically solve your shitty UI codebase.

WebAssembly is going to be the new Tensorflow on people’s LinkedIn
unfortunately, a small word to signal ‘hey, I’m more than just a web
developer’.

Unless you are compiling a video encoder or a video game, like please, just
give a rest. Solve the fact that your simple app is more than 3-4 files and
over abstracted first.

~~~
pjmlp
The reason is the revenge of plugins.

I can have all my plugins back, and this time there is no turning back or
someone claiming how insecure it is, despite lack of bounds checking inside
linear memory segments.

~~~
arethuza
It does look like using webasm for plugins does have some risks - precisely
from the lack of memory accessing checking you mention.

Mind you - I'm hopeful these can be overcome with careful design of the
surrounding application - I'm currently looking at using webasm as a plugin
extension mechanism for an application.

