Baela says hi

Ahoy Montevideo Rustaceans!

Last updated: 2018-09-08

Flaki, tinkering

Mozilla DevRel

Developer Outreach / DevRel

Mozilla TechSpeakers

Mozilla TechSpeakers

Tessel

Tessel Project, JS+HW hacker

Firefox Quantum

Rust & WebAssembly

István Szmozsánszky "Flaki"
@slsoftworks

[]()
Browsers

…a.k.a. What To Expect when You're (Web)Assemblin'

On Today's Agenda:
Why WebAssembly? Why Rust? Why Rust-WASM?

  • What is Webassembly, what is it good for?
  • What does Rust have to do with WebAssembly?

A little WebAssembly (hi)story

WebAssembly is an MVP, with many more features still to come


The WebAssembly spec (and implementations) currently encompass an "MVP", minimum viable product. WebAssembly (after years of work) shipped this MVP implementation in 4 major browsers, working closely together at almost the same time. This type of coordination required a lot of of compromises to be made, so WebAssembly shipped with a minimal featureset, with a lot more features currently in the work.

But we shouldn't jump ahead…

To really understand the motivations behind WebAssembly we have to go back - waaay back - to the beginnings of compiling to the web and the up-and-coming new kid on the block: asm.js

ASM.js

  • The compile-to-web movement is already >5 years old!
  • ASM.js kickstarted something new…


With JavaScript engines getting faster and the improvements in JIT compilation, what was previously impossible (or simply unbearably slow), it became possible: asm.js landed in 2013 in Firefox Nightly and promised compilation of low-level code into JavaScript, to be executed at high speed inside the same JavaScript VM as any other JS.

Compile-to-JS wasn't born with ASM.js (GWT and others have been targeting browser-js as an output before it), but it is what made really it possible to target the browser with large, low-level codebases, yet keeping it still fast enough.

ASM.js was really fast

The "Epic Citadel" Unreal 3 demo running smoothly in Firefox 20 thanks to asm.js

Compared to what was possible before, asm.js was mind-blowingly fast and amazingly easy to use. Entire C++ codebases compiled to JavaScript, and ran close to native speed (half of native speed, but hey, still!) - including whole AAA game engines like the Unreal Engine in all their 60 fps glory…

ASM.js wasn't completely new

  • Same language, same VM, no plugins
  • "One JavaScript"
  • Iterative update to the existing ecosystem

But how? Easy, JavaScript JITs were already doing optimizations, they just needed to gather implicit type information (while running the code) and speculate about the variable types. So what if we could just supply this implicit type information within the code itself? Poof! Asm.js was born and JIT-s were compiling pre-annotated JS code ahead of time. Code that you arguably wouldn't write by hand (and wouldn't really want to read, either) - but code that was still JavaScript, after all.

Still JS, albeit a little strange

Asm.js is a "JavaScript subset" - the same engine parsed the code as the JS

And asm.js wasn't a new language, that promised performant code and breaking away of JS's shackles - looking at you, Dart. It was just a clever subset of JS - but still valid JavaScript code at the end of the day. Could be run on any JS-supporting VM (whether it'd be fast, though—that'd be another question…)

"2x slower" is the new "blazing fast" :)

  • You wouldn't really write it by hand…
  • The Asm.js-compilation preserved the type informations of source language
  • Code is compiled/executed by the same JS VM!


Asm.js was still JS - and that meant the Asm.js compiler/VM was…simply the JS VM! Not another VM, same engine, same compiler, same optimizations, same memory (and garbage collector), same (secure) sandbox. And even though everything was the same - the world was never the same again. Eventually, Asm.js got from 200% to 133-160% of the performance of native-compiled C-code for some workloads.

There was just one tiny issue…

except…

Parsing JS is dog slow…

Asm.js was just JavaScript. Unfortunately parsing JavaScript is not really performant. Like really, really slow. Especially on mobile, but yeah 1-2 megabyte per second is a good baseline metric to keep in mind (and this is just the parsing, compilation is just after this), except for the fastest desktop CPUs.

Parsing JS is dog slow…

On the web we try to avoid multiple-megabyte bundles — but who are we to tell a complete AAA game engine that they shouldn't be clocking in at 45 megabytes once compiled to type-annotated JavaScript code..?

Enter WebAssembly?

WebAssembly can be treated as an iterative succession to Asm.js. It's smaller, faster, more robust in every way - and more easily extensible, created from the ground-up keeping this in mind, making it much more future proof.

What is WebAssembly?

  • Fast & efficient
  • Safe sandbox
  • Integral part of the web platform


If JS is slow to parse, why not make our own, optimized binary format? More compact, easier to parse.

JITs are running on real hardware, so let's make our code's types fit this hardware more - (almost) everything is a number! (…now with 100% more 64-bit types!)

But still runs in the exaxt same JS VM, uses the exact same low-level optimizations, and lives in a symbiotic relationship with the host browser, JavaScript, DOM etc.

Your go-to "compile-to-the-web" tool:
Emscripten


…it even uses the same tools: Emscripten, Mozilla's go-to tool for C++-to-JS compilation has full support for WASM, and even prefers it.

There are other tools, as well, Rust for example has really mature out-of-the-box tooling support for WASM output.

WASM has some cool tricks

Emulating Netscape, running inside Firefox? Because why not…

Really cool ones

A JSLinux emulated x86 VM running Windows 2000 - inside the browser using WASM

WASM is not a toy

…well, okay, maybe sometimes it is…

But it's good for business!

WebAssembly allows the web platform do things that previously were not possible, not economical, or both.

But is WebAssembly trying to replace JavaScript??


And this is an important point. WebAssembly wasn't created to replace JavaScript - it was created to replace Asm.js. It was created for offloading demanding computation into a more optimal format, while JavaScript is there for you to cater for scripting, interaction and various other aspects of the browser. They work together hand in hand more than against each other.

Again: sure it's possible to do data-crunching in JS, or an entire website in WASM, it's just not practical, economical and is not something those tools are good at.

Even inside your browser, there's WebAssembly!

Firefox actually uses WebAssembly inside of the browser, to speed up some performance-sensitive computations in the Developer Tools, which have (for some time now) been written in JavaScript (for a variety of reasons, but this is a topic for an entire other talk).

Rust <3 JS


But enough about WebAssembly - we are at a Rust meetup, so what does Rust have to do with any of this?

Rust loves JavaScript!

Rust <3 WASM <3 JS

…and the reason is because Rust loves (and compiles to) WebAssembly, which, in turn, can help it interact with JavaScript. This is great because Rust is focusing exactly those aspects WASM is trying to solve for JS - speed, safety - while trying to maintain the ease-of-use of a high level language.

The Rust-WASM Pipeline


JavaScript doesn't exist in a vacuum. The language exists in its ecosystem, that consists of millions, probably even billions of lines of shared code - npm packages. Various tools have made it possible to reuse code (whether ours or others) in JS projects - and there is a plan to make WASM interact and integrate with this same ecosystem.

There is an entire pipeline envisioned, from the original source language code (be it Rust or otherwise), through various tools producing an NPM package just as easily (re-)usable and embeddable in JS projects as any other JS package.

wasm-pack

wasm-pack lets you generate NPM packages out of Rust-generated WebAssembly code

wasm-bindgen

wasm-bindgen helps you ease the communication between your code (WebAssembly) and JS

Rust <3 WASM <3 JS

One's code can be seamlessly turned into WebAssembly modules that:

  • Operate on native JS language elements (js-sys)
  • Call browser- & node-native API-s or DOM methods (web-sys)
  • Even interact & call into with other JS libraries!

…all this from within the original Rust source!

But why Rust ?

Hack without fear in Rust

  • Safe, Fast, Parallel
  • Great package manager
  • Minimal runtime
  • Lots of web people :)

Speed ⚡ Without Wizardry

Speed without Wizardry - by @fitzgen

But: Go

  • Go now supports WebAssembly compilation
  • It will compile in its own runtime, though

But: TypeScript

  • You cannot really compile JS to WebAssembly
    • there would be really no point in doing so, at least
  • TypeScript, on the other hand, is a different story!

Extensive (and growing) tooling!

Shameless plug…

Come to NodeConf Argentina in October!

2018.nodeconf.com.ar - I'm speaking, among other things about WebAssembly & giving a workshop in October in Buenos Aires

Come to Rust LATAM in March!

rustlatam.org - Lots of amazing things, talks, workshops. Learn more about Rust, WebAssembly and many, many more exciting topics! I'll be there. ;)

Thanks!

talk.flak.is/wasm

Mozilla Hacks @mozhacks

Flaki @slsoftworks

Keep on Assemblin'!

Reading list: