Conf42 JavaScript 2021 - Online

Supercharge your JavaScript with Web Assembly

Video size:

Abstract

Browser and Web APIs along with JavaScript have seen an incredible amount of development and enhancement over the past decade, however they still have certain limitations. With the rise of Web Assembly we can very easily enhance JavaScript and give our application(s) access to low-level processing and potentially transform web experiences.

By the end of the talk attendees will have a throughout understanding of Web Assembly, and why it’s such a great option for extending the capabilities of the browser and JavaScript via two real life examples where one project was brought from C++ to JavaScript and the other was a brand new project simple leveraging the capabilities of Go within a JavaScript context - both to work with images on the web.

Summary

  • Tamash is a senior developer experience engineer at a company called Cloudinary. Today he will talk about how to supercharge your JavaScript with Webassembly. There are some things that JavaScript is not good at, such as heavy processing. You need something that has lower level access than JavaScript.
  • Web assembly allows you to execute non web based code at a near native speed on the web. It allows us to have an application written in C Plus plus and then be able two run that inside the browser itself. JavaScript and Webassembly actually complement each other.
  • Webassembly allows you to compile your Go project two web assembly module. Because of the static typing, your performance is always going to be the same. All of the modern browser now support this technology. Feel free to experiment web assembly today.
  • One is a c plus plus port to the web using webassembly, and the other one is a Go project. C Plus plus project is able to tell us if the same two images look and feel the same based on their quality. At cloudinary we use technology to determine if quality reduction of an image is visible to the human eye.
  • Go allows you to further analyze the images that are returned from cloudinary. Based on the browser that you're using, we can select the appropriate image format. Take a look at the various project that are out know via Webassembly.

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.
...

Tamas Piros

Senior Developer Experience Engineer @ Cloudinary

Tamas Piros's LinkedIn account Tamas Piros's twitter account



Join the community!

Learn for free, join the best tech learning community for a price of a pumpkin latte.

Annual
Monthly
Newsletter
$ 0 /mo

Event notifications, weekly newsletter

Delayed access to all content

Immediate access to Keynotes & Panels

Community
$ 8.34 /mo

Immediate access to all content

Courses, quizes & certificates

Community chats

Join the community (7 day free trial)