Transcript
This transcript was autogenerated. To make changes, submit a PR.
Hello and welcome to my talk titled supercharge your JavaScript
with Webassembly. My name is Tamash and I work as a
senior developer experience engineer at a company called Cloudinary.
Furthermore, you also see my various contact details on this slide.
Please feel free to follow me on Twitter.
So today I'm going to talk to you about Webassembly, and in
order to get started we need two go back a couple of years,
and we need to take a look at this very, very simplified view of
the web platform. So think about it this way. You have your browser,
and your browser is capable of executing JavaScript
code. You write some JavaScript and that magically does its thing
inside the browser. So there's this virtual machine in the
browser itself that is capable of executing,
interpreting and doing all sorts of magical things with your JavaScript code.
And this is what is available in the browsers today. Brand it was available
for a couple of years now, and it's going to be an important point
that I'm going to make to you later on with regards to this particular
slide. Now, there's no denying in the
fact that the web is growing at an incredible rate.
So the things that we release, the things that we consume,
are highly performance. They try to achieve a lot of things.
We try to use video, we try to do a lot of processing
inside these browsers and on the web brand.
Essentially the main language that we use is JavaScript,
and we just try to push JavaScript to
its limit. And in fact, let me just rephrase this sentence,
and I'm going to rephrase it to say we push a language
well outside its comfort zone. Now if you remember,
JavaScript was not really intended to be the main programming language
of the web, and now there are a vast number
of frameworks and other tools and libraries that rely
heavily on JavaScript. But that wasn't the intention. Now, JavaScript is
a beautiful language, don't get me wrong, and all these features
in the browsers are trying to get the most out of the language.
The language is still evolving, which is a good thing. But there are some things
that JavaScript is not really good at, and probably it
will never be good at, things like heavy
processing things, cpu heavy tasks and so on and so forth.
So all these low level tasks are
either two complex, or they could introduce some
performance bottlenecks inside your application. And of course I mentioned
that before, but let me just say that again, that all the v eight and
these other compilers that you have inside your browsers are
doing an amazing things to do, performance optimization,
but sometimes you just can't do it because of the way how JavaScript
is written. So of course thinking about this,
there must be a better way to allow low level access and
farts code execution at the same time, right?
So there may be a use case where JavaScript
is just not good enough and you need something that has lower level access than
JavaScript, performs better than JavaScript, and so on and so forth. And this
is when we need to say hi to webassembly. Web assembly
is something that wasn't introduced recently. In fact,
here's a little timeline and a historic overview for you. Back in
2013, I believe it was the Mozilla Labs who created ASM
js which really just allowed us to execute
code written in a c on the web.
Okay? Now webassembly two years later had its
first announcement. Another two years after that an MVP was
created brand believe it or not, since 2019
web assembly part of the official w three C recommendation
list. So HTML CSS JavaScript
and since 2019 Webassembly is
also part of the recommendation list and what web assembly.
Now if you go to the MDN documentation, which I really
really like, you will find a very good paragraph that
describes what web assembly, but it's a relatively complex paragraph.
And so I came up with my much simpler explanation as
to what webassembly is. And very simply put, it allows
you to execute non web based code at a
near native speed on the web,
okay? So it allows us to have an application
written in C Plus plus and then be able two run that
inside the browser itself. So we're going to take a look at can
examples of this later on. Now what
is this connection between JavaScript web assembly?
So there is this thing called the webassembly JavaScript API,
and oftentimes I hear that people,
you know, Webassembly is the next javascript, it's going to eliminate JavaScript,
it's going to take over the web, and JavaScript is going to be diminished
and forgotten. And these things couldn't be further
from the truth because JavaScript and Webassembly actually complement
each other, okay? And they do
this by the Webassembly JavaScript APIs, which is a set of functions
and a set of functionality that allows you two consume webassembly
modules from within your JavaScript application or from
within your web application. And what
this allows you to do is to essentially use the power
that comes web assembly and utilize the flexibility
that you are used to when working with JavaScript so to
me this is an ideal mix between the two worlds.
So the question is, how do you actually create
a webassembly module? What is the process that you need to go through?
If you want to use web assembly JavaScript API, you want to do something web
assembly, how would that look like? So here's a simple example for you.
So you write some code in a native language,
okay? And this could be c, C and
a number of other languages. And here's a very simple example for you
where we have a square method written in c,
takes an integer as a parameter and then returns that number squared.
Very very simple. Now what we need to do,
we also need to install a tool called mscripton,
okay? And to install that it's relatively simple. Just go to mscripton.org,
I think that's the website, you set it up to your machine
and then you will have access to the eMcC command line tool
which is the M JavaScript brand compiler. And then you essentially
take your c file, you specify a number of
options and notice resume equals to one.
And then you have some extra exported runtime methods in
here, and then you have the o square js. So you
essentially run this command which is then going to create two things
for you. It is going to generate a square js file
brand, it's going to create a square wesm file. The WeSm file is
going to be web assembly module. And what is the square js
then? So the square js is what you would call a
glue code. So that code is used
to tie the webassembly module together
with Javascript so that you drop that js file into your
application or into your web app, and then you will be
able to access the methods that you have exposed from your c function,
from your c application. Even so, all you need to do now is
load webassembly via Javascript and this is how you would
do that. And notice I'm using module on the runtime initialized.
I have access to that because I've added that glue code square
js to my app. And there are a number of ways
that you can do this. And this is just a very simple way
of accessing web assembly module and the function that we
have in c just to save some screen estate here. So I
created an API object where I have a calculate square method that actually
references the in square method that I have specified
inside my c file. And then notice that for the event
listener for the button I can go ahead brand, just write
regular Javascript, I can take a number from can input field and I
can send that to API calculate square which
is then going to do the squaring of the number
using the webassembly module. Right. Now before you tell
me that you can square numbers in Javascript, I am
very well aware of that. But the point here
is to just show you how easy it is to have something in c
and then bring it to the web using mscripton
brand webassembly modules. Okay? And then the last step is of course you
just need to run your web app. And as a final reminder,
just remember to always use to glue code. So that's the code
that these compilers like the emcc brand,
some others would produce. Because if you don't add that to your application then
you won't be able to interact with the Webassembly module or life is
going to be a lot more difficult. Also, if you're
doing a progressive web app that may use web assembly module, just make sure
that you add the glue code as part of your cached
offline assets as well.
Okay, so on this note,
non LLVM languages, so a language like Go work
slightly differently. So if you are a Go developer,
you're familiar with the Go programming language, then just know that
you can also compile your Go project two web
assembly module. So go has a compilation target for
webassembly. However, things will be slightly different.
Now I have an example of this where I'm going to highlight the differences
for you. Actually with Go the glue code is something that
you need to download from either the Go website or from their GitHub
repositories. And with Go you can
actually have direct DOm access from your
Go project as well. So it's slightly different than how a c or a c
project would work. Now of course,
why would you want to use Webassembly? Why would you want
to choose this technology for your next project? That's a very good question.
And I tried to select a couple of points that
either I have used or I heard other say
was valid use cases. So reusing existing code, I think that's
a very straightforward one because you have maybe
an order C or C Plus plus project that you want to now
run on the web, maybe does some audio manipulation, some video manipulation,
image manipulation, something that is very low level processing
that you really don't want to recreate in JavaScript, or you cannot recreate
it in JavaScript, you can just port those to the web.
Predictable performance is an interesting one. I would
talk about that in combination with the binary size. So when
you have some JavaScript file and the v eight engine runs
through with its magic on top of that
you get various performance optimizations, but those
happen kind of on the fly, whereas with web assembly
module, because of the static typing and the way how you just create web assembly
module, your performance is always going to be the
same. There is not going to be varying levels of performances
based on how your entire application is written, right? So the performance
and the binary size of the webassembly module is always going to
be the same. So it's a given, it's not going two change.
And the last use case could be where you want to have some advanced
system access. So maybe you don't want to run threads,
you want to do SIMD, you want to have shared
memory. So all these advanced features that you do not have currently in JavaScript,
then Webassembly is a very good option for those. In fact,
in a recent project I was using two versions
of the Webassembly module for the OpenCV
library. One was with SIMD enabled and the
other one was without SIMD, and I could achieve
double the FPS for a video based
project that I was working on. So you see the difference is significant
in there as well. So putting all of
this together, this is how the webplot formula looks today. So if
we take a look at this very simplified view again, what's happening inside
our browser, we have a virtual machine,
but that virtual machine is now capable of executing both
our JavaScript and our Webassembly code, and that's
how it is today. As I said, it's official.
It's part of most of the modern browser. In fact, I think all
of the modern browser now support this. So feel
free to experiment web assembly today.
So let me show you a couple of demos as well, and I'm hoping that
they will be successful. So I'm going to show you two projects.
One is a c plus plus port to the
web using webassembly, and the other one is a Go project.
So let's start with the C project here. So let
me just open a browser as well.
Okay, so Similecra
is, as you can see, a c plus plus file,
and simulacra is short for structural similarity, unveiling,
local and compression related artifacts. Very, very simply put,
this C Plus plus project is able to
tell us if the same two images
look and feel the same based on their quality. And at
cloudinary we use this particular technology to
determine if the quality reduction of
an image is actually going to be visible to the human eye.
Okay? And this is a c plus plus project. It has
always been a c plus plus project. It basically asks you to
compile this. You will get the simulacra binary and then parameter one
in your CLI should be the first image, and then parameter
two is going to be the second image that you want to compare. And then
similar query is going to return you a number.
And as you can see here, if the number is one or close to one,
those are very different images. So you will have some very visible
quality differences inside the image.
Generally speaking, anything below
0.1 should not be visible to the human
eye. Now I thought this is a great project, why don't
we have a web version of this? And so what I had
to do was of course port this web assembly. I used
mscripton to do this. I actually wrote a blog post about this.
So if you're curious, you can take a look at how this whole project was
ported from C web assembly.
But what I have here, once I have the
webassembly module and the glue code,
I could very easily just load web assembly
module. And what I'm doing is grabbing two
images and notice that I have this right file method
here. So when you web assembly, you get access to
the browser's virtual file system where you can
write and read files from. So that's another very interesting use
case. So I'm writing the two images and then I do the
similar calculation for both, and then I just return that and I built
a very simple UI for this particular tool. So what
we can do, we can fire up an HTTP server
and then I'm going to go two my browser and
just open up port eight nine, and then we're going to take
a look at how this project looks like.
Actually before I do that, let me just copy this particular image
and you will notice that this is an image of a
car. So this is the unmodified,
100% quality, highest quality version of
the image. And what I'm going to compare it with is Q underscore
one, which is of course going to reduce the quality of the image to
quality one. So it's going to be very, very pixelated. So you see, this is
a terrible, terrible looking image. Now at
cloudinary we have a feature called Qauto,
which is automatically going to reduce the quality of the images in
a way that is not visible to the human eye. So if
I put Qauto, then you will get again
a high quality version of this image.
But the difference is that if I take a look at the network panel
here real quick, and if I try to also
zoom in a little bit here for you,
you will notice that this particular image
is 732 kb in size. But if I remove
to q autos, if I take a look at the original, then that's 1.4
megabytes. Just by adding q auto, we shaved 50% off from
that image. But the question is, can we
see the difference? So if I put the same two URLs
in here, then we're going to be getting a zero,
indicating that these images are exactly the same. If I put Q
underscore one, then I should get a very high
number, a number close two, one. So 0.4. And as I said,
anything above 0.1 means that humans will have
perceivable quality differences between the images.
And let's finally verify Q underscore auto.
And that is 0.3.
So in fact, this tool tells us that these two images
do not have any sort of artifacts that the
humans, human beings would in fact see.
So this is the C Plus plus project running
in my browser, because I was able to pull this
from C Plus plus web assembly and then add it to
the web. So that's one of the use cases. Now, the other project
that I wanted to show you is a project
that was written in go. So in the same way how cloudinary
has Qauto to automatically reduce the quality of the image,
we also have f auto, which is short for automatic format.
So based on the browser that you're using, we can
select the appropriate image format or the best image format for
that browser based on the analysis of the image
as well. And of course you can take a look at this inside
your browser. So let's go back to this image, and if I now open
up the network panel, and if I just do can
f auto in here, so I do f underscore auto,
then let's take a look at the headers.
So this is a JPEG, but if I shrink this down to,
say, width 500, so this
is a 500 pixel version of this image, then because
I'm using a chrome browser, I am now getting a WebP image.
And I thought, this is great, but I would like to further analyze
the image itself. So how could I do that?
And well, the answer
was that I created this go project where
I used some libraries like
Lib WebP and Lib PNG and some others to further
analyze the images that are returned from cloudinary.
So as opposed to just saying that hey, this is a web P,
I can now tell whether it's a webp with an alpha channel. What is the
container for that web image? Is it a vp eight? A vp
eight l, so on and so forth. If it's a PNG, I was able
to analyze the bit depth,
what kind of interlacing it has, and so on and so forth.
And I mentioned that go works slightly differently. So notice this WeSm
underscore axe js file, which is essentially my glue code.
And then I have main go where if you take a
look at a line like this one,
even though this is a go file, this file looks
really familiar, right? Even if you've never seen go, but you know JavaScript.
So this is essentially saying document getelement by id
response text and then set the inner HTML to
something so I can essentially manipulate my Dom
from within my go context, which is very, very useful.
And then executing this very simple command, I was able to
build the webassembly version of this go project.
So let's take a look at how this looks like by
opening up another server. So let's port 9999.
And
this is my project. So this is that f auto flag already
in here. So let's add width 500 and let's
use the built in user agent, which is in fact going
two be a chrome. So let's hit check. And this is
a lossy webp with a vp eight container
that has no alpha channel. But what if I go to say
gem Darth Vader Png?
Well, let's see, what do we get? Okay, so this is now
a VpaX container that is lossy,
and it does have an offer channel. Okay,
this is perfect. So let's see what happens if I just refresh
if I use f auto with 500, with a
browser that does not support webp.
Now here's a sort of additional trick for you.
You can actually change the user agent by
using the network
conditions panel using the developer tools
in Chrome. And I'm going to just say that I am now on
a Safari Mac. Safari Mac does not support
webP. So let's see what happens if I call the same image.
Well, it just returns a JPEG image,
or if I remove the width 500, is this still going to be a JPEG?
No, now it is a JPEG 2000, which is in fact
an image format supported by the Safari browser.
So this particular tool allows me to dig one level
deeper and analyze these images further. And I could have
taken this to a whole different level
by just manipulating the go code. So I'm going
to leave you with some resources. Take a look
at the various project that are out know someone ported doom
via Webassembly to browser squeeze app is
one of the flagship applications that is done
by Google. There are lots of case studies around it, they talk about it quite
often and behind the scenes that also uses
webassembly modules. So take a look at these resources. They're very,
very useful, and I hope you found this presentation
to be useful. And thank you very much
for attendees this session, and I hope you will have the opportunity to try
out webassembly in the not so distant future.
My contact details are on the bottom of the slide, so please feel
free to contact me at any point in time if you have any questions or
would like to know a little bit more about webassembly.
Thank you.