[MUSIC PLAYING] THOMAS NATTESTAD:
My name is Thomas, and I'm the product
manager for WebAssembly. ALEX DANILO: My name is Alex,
and I'm a software engineer on Chrome OS. THOMAS NATTESTAD:
And today we're going to talk to you
about WebAssembly. We're going to
start off by briefly describing what WebAssembly is
and what you can use it for. Then I want to show off some
of the amazing new features that the WebAssembly team has
been working on to deliver to you in this last year. Then I'll showcase some of
the amazing applications that have managed to
build with WebAssembly, and our shipping and production. All right. So first off, what is
WebAssembly, actually? WebAssembly is a new
language for the web, and offers an alternative to
JavaScript for expressing logic on the web platform. It's important to note, though,
that WebAssembly is in no way a replacement for JavaScript. Rather, it's designed
to fill the gaps that exist in JavaScript today. Specifically, WebAssembly
is designed as a compilation target, meaning that you write
in higher level languages, such as C++, and then
compile into WebAssembly. WebAssembly is also
designed to deliver reliable and maximized
performance, which is something that can
be difficult to get out of JavaScript. Most exciting,
though, is the fact that WebAssembly is now shipping
in all four major browsers, making it the first new
language to be fully supported in every major browser
since JavaScript was created more than 20 years ago. All right. So what can you
actually do with this? Well, as I already mentioned,
because WebAssembly offers maximized and
reliable performance, you can now expand
the set of things that you can feasibly
do in the browser. Things like video editing,
complex application, codecs, digital signal processing,
and many, many more performance-demanding
use cases can now be supported on the web. Secondly, WebAssembly
offers amazing portability. Because you can compile
from other languages, you can port not only your
own applications and libraries but also the wealth of
open-source C++ libraries and applications that
have been written. Lastly, and potentially most
exciting to many of you, is the promise for
more flexibility when writing for the web. Since the web's
inception, JavaScript has been the only
fully supported way to execute code on the web,
and now with WebAssembly you have more choice. All right, so now that we
all know what WebAssembly is, I want to jump in and show
off some of the new features that we've been adding
in just the last year. First off is source maps. You likely all know how
important source maps are when you're working with
something like TypeScript or Babel, but it's
even more important when you're trying to debug
your WebAssembly code. Source maps let
you turn something that looks like this into
something just slightly more friendly, like this. With source maps you can see
the specific line of code where an error has
occurred and you can also set breakpoints and have
the program actually pause at the appropriate moment. One of the big feature requests
that we've heard from users is for better performance
when you're starting up your application so that
your module can actually get going faster. And for that we've created
streaming compilation. In the past, when you
wanted to compile a module you had to wait for
the entire module to be loaded off of the
network, and only then could you move on and
actually compile it. Now with streaming
compilation, you can start compiling each
piece of your module immediately, even before
the other parts have finished downloading. To show you what that
actually looks like, here's a simple example where
we called a fetch function-- or fetch for a WebAssembly
Fibonacci module, and then we just passed
that fetch promise directly into WebAssembly.inst
antiateStreaming, and it takes care of all
of this underlying bits and pieces for you to
deliver this experience. We did some profiling at
different network speeds to see the impact of this. We found that all the
way up until 50 megabits per second network
speed, the network was actually the
primary bottleneck, and that the compilation was
done as soon as the module was loaded. It wasn't until you hit the
100 megabits per second speeds that you actually needed
additional time past the time it took to download the
module in order to fully compile and get it going. To make startup
time even faster, the team built and launched
an entire new compiler that we called the
Liftoff compiler. This Liftoff compiler takes
the WebAssembly byte code that comes down off of the wire
and then starts executing it immediately. The WebAssembly module is
then taken off the main thread and optimized further by the
TurboFan optimizing compiler. When TurboFan is done
optimizing the WebAssembly code, it's then hot
swapped in directly without any need for
explicit developer action. Unity did some benchmarking on
the effects that Liftoff had. On a benchmark where they tried
to load a very large game, they found that it went from
taking seven seconds to load the game to less than
one second, which makes all of the difference
when you're waiting to get into a game experience. Probably the biggest
feature that the team's been working on this year
is WebAssembly threads. WebAssembly threads lets you
run fast, highly paralyzed code for the first time
across multiple browsers. It also lets you bring existing
libraries and applications that use threaded code such
as Pthreads to the web. This is such a big
feature that I'm actually going to leave most of the
explanation to Alex later on. But before I get
into that, I want to show off some of the
cool new applications that have already been building
and launching with WebAssembly this last year. First off is SketchUp. SketchUp is a 3D
modeling software that you can learn and
start using really quickly. Unlike traditional
computer-aided design, most people can learn
SketchUp almost right away. SketchUp lets people draw
in perspective and then push-pull things into 3D. In no time, people can draw
and redesign a living room, plan out a
do-it-yourself project, or create and export a
model for 3D printing. This app is a lot of fun and
you should all check it out, which you can do right
now instantly, just by going to app.sketchup.com. SketchUp has been around
for a desktop application, but the team's
strategy has always been to expand and
broaden the market of people who can
use 3D modeling, and by making it
simple and easy to use and accessible to everyone. Delivering the app over
the web was a critical step in that strategy,
and the team knew that they wanted to
use the same code base as their
desktop applications, because rewriting their entire
application in JavaScript was just simply not an option. The team's approach was to use
the WebAssembly and Emscripten compiler to compile
their core 3D modeler and bring it to the web. The initial port took two
engineers only three months to bring to the web, which
is pretty phenomenal when you realize just how
drastically it expanded the reach of their application. The early focus for
SketchUp has always been on the next
generation of 3D modelers, and today SketchUp
is already one of the most popular apps on
the G Suite for education marketplace. At the same time, the app has
opened up a subscription model for SketchUp, and in
just over six months, the team has increased its
paying customer base by 10%. SketchUp has also
seen consistent growth in session time, returning
visitor percentage, and active users. Moving on, the next application
that I want to mention is Google Earth. I'm happy to say that Google
Earth has successfully gotten their application ported
to WebAssembly, including the newly added support
for WebAssembly threads. The best part is
that they actually got this threaded build working
in both Chrome and Firefox, making Google Earth
the first WebAssembly multi-threaded application to
be running in multiple browsers. Google Earth did
some benchmarking, comparing their single
threaded version to their multi-threaded version. They found that the
frame rate almost doubled when they went to
their threaded version, and the amount of jank/dropped
also reduced by more than half. All right, so the
last big company and launch that I want
to mention is Soundation. Soundation is a
web-based music studio that enables anyone
to make music online with a wide selection
of instruments, loops, samples, and effects. No additional hardware or
installation or storage is required. Everything is accessible
instantly and everywhere. Soundation's mission is to
facilitate musical creativity in the world, and they
do this by offering a powerful, accessible,
and affordable service to the growing demographic
of casual producers. As an online web app,
Soundation streamlines the ability for producers
to connect with peers, get feedback, enter
competitions, and even get record deals. Soundation is using
a wide variety of advanced web features to
deliver this smooth experience. And the first of these
is audio worklets. Launched in Chrome
66, the audio worklet brings fast performance and
extensible audio processing to the web platform. It could be used in conjunction
with other cutting edge web technologies such as WebAssembly
and SharedArrayBuffer. Soundation is also one of
the world's first adopters of WebAssembly threads,
and they use these threads to achieve fast parellelized
processing to seamlessly mix songs. So let's have a look
at their architecture and see if we can
learn anything. On the JavaScript
side of the world, they have their application UI. That application UI then talks
to an audio mixing engine. This audio mixing
engine then spawns off multiple different worker
threads in WebAssembly, and each of these
worker threads can talk to the same piece of
SharedArrayBuffer memory. This SharedArrayBuffer
memory is then passed on to the mixing
threads, which further passes it to the audio worklet, which
produces the final result. Here's a visualization showing
the performance improvements on rendering a song as they
added multiple threads. Adding just a single
additional thread doubled their performance,
and by the time they've added five
threads, they had more than tripled the performance
of their application. So that's a great visualization
showing the performance improvements that
thread can bring, but since this is Soundation,
I thought we would instead try and listen to it. So here is us trying to
render a song in Soundation in the single threaded
version of WebAssembly. And fair warning,
this is not going to be an entirely
pleasant experience. [STATICY MUSIC] So as you can imagine,
this is not the experience that you want when you're trying
to create beautiful music. But luckily Soundation succeeded
in launching with WebAssembly threads, and now
they're able to deliver an experience that sounds
just a little bit better. [SMOOTH MUSIC] So as you can see, not
only is this a much more pleasant experience,
but the CPU also has additional cycle
for other work. All right, so I want to close
off my segment by just talking about some of the
amazing community projects that we've seen
people working on out there. And the first of these
that I want to mention is the awesome work that's
been done by the Mozilla team and the Rust community
to bring Rust to the web through WebAssembly. They have an awesome set
of tools and materials to help you get started,
and you can check those out at rustwasm.github.io. Speaking of
languages, we've also seen more than 30
different projects trying to bring other languages
to the web through WebAssembly. These languages include ones
like Perl, Python, Ruby, Kotlin, OCaml, Go, PHP,
and the .NET framework. Many of these languages
require garbage collection, which isn't currently
something that's supported in WebAssembly,
though we are working on it. These languages come to
the web by actually taking their garbage collection
system and other runtime bits and compiling that itself
down to WebAssembly, and then shipping everything
down to the application page. This is a great strategy
for getting started and experimenting with some
of these languages on the web, but because of some of
their performance and memory characteristics, these
aren't currently suited for production applications. The fully supported languages
today are C, C++, and Rust, but everything else should still
be considered experimental. And there are so many more
amazing community projects that I don't have
time to do justice. We've seen people porting
Gameboy emulators, GNU libraries, digital signal
processing, and even entire operating system like
Microsoft Windows 2000 now available in a
browser tab, which is, if not a exactly
pleasant experience, definitely interesting. You can check out
all of these demos and much more at the forum
where we have multiple demos set up for you to check out. And with that, I want to
hand it back off to Alex to talk to you more
about WebAssembly threads and how to use some
of these features. [APPLAUSE] ALEX DANILO: Thank you, Thomas. One of the kind of big
things at the conference here, when we talk
about the browser, we talk about
using the platform. And quite often people think
of the platform as the software stack that's inside
the browser, but I like to think of it a
little bit different. I like to think about the
hardware, the platform that's actually in your machine. So here is an artist's
rendition of the inside of a desktop microprocessor. This is what you
see today if you take the plastic off the top. So at the top, we
have the green bit, which interfaces to
the PCI bus, used to be called the northbridge. The left and right, you
have memory interfaces. These little yellow boxes are
integrated memory controllers. And you see all these
blue tiles here. And what they are is cores. So each of those is a CPU
core in its own right. So this may be a desktop
microprocessor, but even in your pocket, if you have an
iPhone or an advanced Android phone, you'll have
something like six to eight cores in
there, ready to be used to do good computing work. So when you write a
normal web application, you're looking at
something like this. You have one core
running and so you have all this silicon doing nothing. So you're not really
using the platform. Now we've seen people come
along and do something like spawn a web worker
to do the hard work, and have the main thread for UI. In that case, you're running
a double threaded application. And so you're using the
platform a bit better, but you're not really
doing everything you could. Now since we have introduced
WebAssembly threads, you can do stuff like this. You could actually use many
cores for your application. And as we saw with
the Soundation demo, there's visible improvement
in the user experience. So I'd really like
you to start thinking about how you can
adapt your application to use all these cores. Now when you create
a web worker, you have to understand that
that is a threading primitive and they run concurrently. So you can do
compute in parallel. And this is a primitive that
we all know pretty well. But one of the things
about when we do something like this, if we have
an app, on the left, we have what we call
the main thread-- we're all familiar
with the main thread-- that interacts and
talks to the DOM. The worker that we
generate is what we call the background thread. So it's running in parallel
but it doesn't actually have the ability
to call web APIs and interact with the
DOM and stuff like that. But when you create
workers, and you create them normally with a JavaScript
thing, it creates an instance. So these instances kind of
sit on their own on the side, they're running
parallel, they don't get to do anything with the DOM. So they kind of run on the side. So if you create one,
you get V8 hanging off the top of your main thread, and
you get an instance hanging off your worker. So then if you go and
create a bunch of workers, you get a bunch
more V8 instances. Now each of these
instances consumes memory. So that means that if you start
spawning lots of JavaScript workers to make your application
do stuff more complex, it will actually consume
more and more memory and you might run out on a
phone, or something like that. But I'll let you in
on a little secret. They don't talk to each other. So you've got separate
bits of JavaScript running in all these
parallel threads, but they don't communicate. They don't have
any shared state. They're literally another
copy of V8 sitting in memory. The way these things
can talk to each other, though, is with postMessage. And postMessage is kind of like
sending a paper plane over. I'll send it from this
worker to that one, I'll sit around and
wait for it to arrive, and there's no
predictability about when that will be delivered. So it's not a great experience
for a true multi-threaded application. Now, when the team built
WebAssembly threads, they implemented something that
looks a lot more like this. So what happens is, this
is an example of, say, having three threads. So under the hood, we actually
spin up the three web workers but the difference here is
that the WebAssembly module is shared between the workers. So there is one
copy of the code, so you're not consuming
nearly as much memory. But more importantly,
they share state, and the way they share
state is through a thing called SharedArrayBuffer. So if you're a
JavaScript engineer, you probably know what a typed
array is, because you use them day to day. So SharedArrayBuffer is
basically the exact same thing, except that it can be
shared across workers. And so what that
means is the state of the execution of the
application is visible to any of the workers in parallel. Now if you farm off something
into a pool of workers and you have it hanging
off your main app, it will look
something like this. You'll have your main thread
for your main application that can talk to the DOM, it
can use all the web APIs, and it can see the
SharedArrayBuffer, and that
SharedArrayBuffer is being manipulated by all the parallel
threads in the WebAssembly module. OK, but by now you're
probably thinking, this is all well
and good, but how do I use this stuff in
my actual application? So I'll start with a
very simple example. We'll do an example which is
just a little Fibonacci program that runs in two threads. So it will look a bit like this. There'll be the main thread,
the background thread, the WebAssembly
module, all talking to the SharedArrayBuffer. So we just take
some source code, which will be
something like this, which is just a bit of C code. And what we want
to do is we want to compile that into a form that
we can use in parallel threads. And the way we do that is with
the Emscripten tool chain. So it has a compiler
called EMCC, and there are a
couple of flags here, though, I want to point out. The first one is
-s USE_PTHREADS=1. What that does is turn on
the multi-threading support when you're compiling
your WebAssembly module. The second flag that's
interesting is -s PTHREAD_POOL_SIZE=2. What this does is
tells the compiler that I want to pre-allocate
two threads for my application. So when I actually start
the WebAssembly module it will pre-create two threads
and get going with that. Now this is kind
of visualization what would happen. If you set PTHREAD
pool size to two, you get the picture on the
left, you get two workers, and if you set it to eight
you get eight workers. And that happens at startup
time of your web app. Now you may be wondering why
you care about the number. Well, the thing is that you
should really try and set it to the maximum
number of threads. If you say I only
want two threads, and then suddenly
your application needs three or four, it's
a bit of a problem. So what happens is that
the WebAssembly module has to yield to the
main thread before it can create that worker. So if you're relying on
all the threads being there at the startup, you need
to set the number high enough. But of course, if you
set that number too high, you're wasting memory. So this is something to tune. So in Soundation's case
they used five threads and it works really
well for them. So when you're tuning your apps
you need to think about it. OK, so if you want to get
out there and actually try this stuff, which
I'm sure you're all dying to, if you
fire up Chrome 70 and navigate to Chrome flags and
search for WebAssembly thread support, change the
setting here from default to enabled, and at
that point, you'll have to restart your browser. And then you can start building
stuff and testing it locally. Now once you've built a
working WebAssembly thread app, you probably want to deploy
it out to the public. And the way you do that is by
getting an origin trial token. So an origin trial token
is tied to your domain and you get it from us. And you basically--
it's just a meta tag that you put on the page. And that tells the
browser, hey, these people are trying WebAssembly
threads and let's use it. So if you want to go
ahead and do that, and I encourage you all to do
so, just go to this short link, and there's a form
you can fill in, put in your URL, the reason
you want to use this stuff, and go start building
something really cool. Now of course, as developers,
we spend most of our times in DevTools trying to debug
things, which is how it is. So in Chrome 70 at the moment,
which is released to stable, you can single
step instructions. And that is a
WebAssembly instructions. So it looks a little
bit like this, like not friendly, as
Thomas pointed out. So you can see this
little box up here, which is showing
you the threads. So this is a two thread
application running. And this box is the actual
WebAssembly disassembled code. So it's not the binary, it's a
text form of the instructions that are in the module. And you can single
step those and it's all very well and good, but
realistically, we don't really like that debugging experience. So Chrome 71 brings
source map support, as Thomas mentioned earlier. So source maps lets you
change what you saw before into something--
oop, next slide-- something that looks like this. So this is the source code of
the Fibonacci function sitting in Dev Tools, and you can
single step over instructions, you can set breakpoints, you
can do all stuff like that. Now, if you want to
actually do this yourself and you want to
generate the source map, you just need to set two flags
on the EMCC compiler command line. The first is -g, which says
generate debug symbols, and the second is
--source-map-base, and that points to a URL
where it will actually find the source map file. In this case, I'm
using local host, so I'll be using it
on my own workstation. OK, so I'll just recap on
what we've talked about today, just so you can remember
what we talked about. The first thing is it's
streaming compilation, which lets the browser
compile the WebAssembly module as it comes over the
wire, which is launched now. It's in Chrome 70,
which speeds things up. The second is Liftoff, which
is the tiered compiler, so you get the first compile
really fast so your app starts, and then hot swaps in the
better code a bit later on. Then we have, of course,
WebAssembly threads shipping now in Chrome 70, and you can
use it with an origin trial, so you can ship it
to your customers and they can use it
and play with it. And of course, Chrome 71,
which will be out really soon, contains source
maps, which means that it's a lot easier
to debug your code. And so I'd encourage
all of you people out there to start writing
using WebAssembly threads, because it unlocks the power
of the supercomputer that's sitting in your
pocket right now. Thank you. [MUSIC PLAYING]