WebAssembly: A new development paradigm for the web

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments

Tier list for further context. Both JS and TS rank below Kotlin.

https://youtu.be/FEpqJdeKjzk?t=737

πŸ‘οΈŽ︎ 1 πŸ‘€οΈŽ︎ u/Marble_Wraith πŸ“…οΈŽ︎ May 28 2023 πŸ—«︎ replies
Captions
[MUSIC PLAYING] THOMAS NATTESTAD: Hi, everyone. My name is Thomas. Along with my colleague Vivek, we will be covering WebAssembly and how it's enabling a new paradigm of web development. So let's start off by covering what WebAssembly actually is and why you would use it. Well, WebAssembly is a low-level binary format for the web that is compiled from other languages to offer maximized performance and is meant to augment the places where JavaScript isn't sufficient. So why use WebAssembly? Well, there are three main advantages. First, it offers more reliable and maximized performance. Second, it enables great portability since you can compile from other languages, enabling you to share your code across deployments. Lastly, it offers greater flexibility for developers who can now write for the web in languages other than JavaScript. Perhaps best of all, it is now shipping fully in every major browser, so you can reliably reach all of your users. In this talk, we want to go over four languages to show how they're coming to the web and how you can get started yourself. We're focusing on these four languages in this talk. But it's worth noting that there are a ton of other languages that are also adding support for WebAssembly. So let's dig in and start off with C++. One of the earliest areas where WebAssembly transformed the web was by enabling large applications, such as AutoCAD, Figma, and most recently, Photoshop, on the web. These are performance demanding applications with large code bases, often ported from other platforms. AutoCAD brought their code base, which was started over 40 years ago, before the first ever browser. And now, parts of that original code base are directly accessible with a simple link. Figma made a big bet on WebAssembly from the start and wrote their Engine in C++ for maximized performance. Photoshop has brought their complex application to the web, enabling easy sharing across platforms with commenting and editing. They'll also soon be using Web ML for optimized machine learning operations, which you can hear more about in the What's New with Web ML talk here at I/O. In the last year, we've continued to see more of these incredible advanced apps, leveraging Wasm to come to the web. Snapchat wanted to expand their audience while using a single code base to hit all of their platforms. They decided that C++ would give them the performance and portability that they needed. By leveraging WebAssembly, they can deliver their entire application directly in the browser across all operating systems. Snap is also investing in bringing their amazing camera kit to the web through WebAssembly, which you can try yourself right at web.snapchat.com. Here, they're again reusing their C++ implementation that is shared across platforms. They're using Emscripten, including its Embind binding systems, and OpenGL to WebGL conversion. They're also using TensorFlow.js for ML inference, Web Workers for off-screen rendering, and performance optimizations using the Chrome profiling tool. WordPress has done something rather incredible and actually managed to get the WordPress server environment built to run directly in the browser. This relies on compiling the PHP interpreter itself and SQLite to WebAssembly. With this, users can try out WordPress directly in the browser with zero setup. This is amazingly impactful for getting started, enabling interactive tutorials, and eventually supporting easy publishing of backends. By running on Wasm, they can now also deploy to non-browser environments, including Node.js or other Wasm server environments. You can read tons of interesting details in this deep dive blog post. All of these examples are powered by the Emscripten toolchain. Emscripten will help compile your C++ code, but also helps port code built against POSIX APIs, and will even translate OpenGL calls to WebGL. To get started, go to emscripten.org. We've also made really substantial improvements in enabling WebAssembly debugging. With this support, you can now see your C++ code in DevTools, set breakpoints, step through your code, and even see runtime values of variables. Visit this link to see how. Now, you might be thinking to yourself, I'm not writing C++ or building a large cross-platform application. I'm doing web development. Well, this is where WebAssembly libraries are going to change your life. These libraries include things like OpenCV for image analysis, TensorFlow.js for ML, Skia for graphics, SQLite for database, FFmpeg for video manipulation, and so, so much more. You can dig into these examples at this URL. These examples all expose JavaScript APIs. And you might not even know that they're powered by WebAssembly under the hood, except for how amazingly performant they are. So let's take the incredible web app for Telegram as an example. Telegram is a traditional web application with the majority of functionality built in JavaScript. But there were a few areas where they needed some additional functionality that they found in WebAssembly. Specifically, they use the RLottie renderer for animated stickers, Opus Recorder for voice recording and decoding, fastTextWeb for language detection, and Webp-hero for dot Webp support in Safari. And indeed, when looking at MPM, there were 1,500 packages with WebAssembly. If you're a library author in really any language, and you're interested in bringing your library to the web, now is your moment. If you'd like to connect directly with us, provide feedback on your experience, or even get featured on web.dev, you can visit this link. So now that we've covered C++, let me jump into Swift. It's been possible to compile Swift WebAssembly for a while. But it's only recently that the toolchain and ecosystem have matured to a point where this is truly shippable in production. One such application that is shipping Swift on WebAssembly in production and coming to the web is GoodNotes. They have invested a decade of work in creating the most incredible iOS application, full of cool features with a 4.8 star rating. They decided it was time to spread their application to non-iOS users. And rather than having to do an incredibly expensive rewrite that would also have to be separately maintained, they decided to reuse their Swift investments through WebAssembly. This means their decade of work can be reused, while also minimizing maintenance costs. When we talked to them, one of my favorite things they said was, quote, "every day, our iOS developers contribute something new to our Swift code base. And our web app benefits from that." In terms of their tech stack, they're utilizing Swift on WebAssembly, React as their UI framework, and PWA for installability. They have a great Tech Talk with lots more details at this link. They do their surrounding UI in React, and have a central Canvas connected to the Swift Engine. This is the same pattern that we saw with our previous partners. As an example, when a user clicks something like Add Page, it calls from the click handler in React into the Swift code base to add the page and then make it ready for input. The toolchain they use is called SwiftWasm. And you can get started with that on swiftwasm.org. The toolchain includes JavaScript kit, which enables your Swift code to interact with JavaScript through bindings and translating types and objects. It also offers Carton, which provides a Swift alternative to something like webpack. It lets you easily bundle and deploy your app, while also shipping your code to other platforms. As with anything, there are some limitations that developers should be aware of. I want to be clear that this isn't a magic button that will make your Swift app run directly on the web. And while it's dramatically faster than a rewrite, it's not zero effort. Swift code and SwiftUI should work well. But things like storage, UI kit, networking, and files need to utilize web alternatives. Still, if you're a Swift developer who has been hoping to expand your addressable market, this is your moment. So now I want to take a step back from any specific language and update you a bit on the progress of the WebAssembly standard itself. In the past, we've discussed how WebAssembly threads and SIMD can offer a 10x or more improvement for performance-sensitive workloads. For an overview of how powerful these features can be and how to get started, check out this video from Chrome dev sub. And we're continuing to expand with even more SIMD instructions to further maximize performance. The tail called proposal is a critical optimization for functional programming languages and enables better support for C++ programs using coroutines. The memory 64 proposal gives applications the ability to reference more than 4 gigs of memory and making it easier to port code that assumes a 64-bit architecture. Lastly, the JavaScript Promise Integration API lets synchronous code access asynchronous APIs without substantial code size or performance overhead. This is a big deal if you're trying to make code that assumes a synchronous environment work with the web. Now, to continue our language journey, I'm going to turn it over to my colleague, Vivek. VIVEK SEKHAR: Thanks, Thomas. You may remember at last year's Google I/O, we previewed our plan to bring new languages, like Java, Kotlin, and Dart to the web. Over the past year, the WebAssembly community has been busy making this happen. So let's talk a bit about what we built and what this new technology makes possible for developers across the web and native mobile platforms. As Thomas mentioned, WebAssembly has taken off among developers using C and C++, as well as a growing community around Rust. In these languages, developers are responsible for, in a sense, cleaning up after themselves, freeing objects from memory after an application is done using them. This class of languages was the primary focus of the early WebAssembly standard, what we call WebAssembly MVP, in part because these were the languages many large desktop applications were written in, and also because they had somewhat simpler requirements when developing the WebAssembly standard. Another class of languages manages memory on behalf of the developer. The languages own runtime automatically finds and frees memory that the app is no longer using. This class of languages is really interesting if you're building web or mobile apps because JavaScript is the language in which the web's own APIs are specified and standardized. And Kotlin and Dart are increasingly popular among developers building cross-platform, native mobile apps. So we wanted to figure out, what would it take to extend the web platform to applications written in these languages in a performant way? So let's walk through how we do that. When a web app starts in the browser, it's given a context for its JavaScript code and some heat memory. JavaScript memory is garbage collected, so there's a garbage collector provided by the browser behind the scenes. Now, when an app instantiates a WebAssembly module, it asks for and is allocated a region of linear memory for its own use. If the developer is using a language like C or C++, then the WebAssembly module uses some of this memory for a dynamic heap. And the developer would handle freeing objects on that heap after they're used. On the other hand, if the developer wanted to use a managed memory language, then the WebAssembly module will need to include that language as garbage collector code to manage the heap and automatically free up unused memory. There were two main problems with this approach. The first is obviously bloat. The WebAssembly module has to ship and instantiate that garbage collector every time the app is loaded. This increases the module size and delays the application startup, despite the fact that every standards compliant browser out there already contains a garbage collector for apps to use. Another form of bloat comes from the need for developers to have a kind of clairvoyance when deciding how much memory to request for their module. To avoid crashes, the typical thing to do is to set a maximum memory size that is just beyond the upper bound of your anticipated memory needs. This puts more pressure on implementations who have to manage the apps JavaScript and WebAssembly memory separately, alongside the memory needed by other apps and tabs that the user might be using. The second problem is what I call the split brain problem. In this architecture, those two memories and their garbage collectors know nothing about each other. This means developers need to be careful to architect their applications to avoid corruption when, for example, the JavaScript garbage collector comes along and frees up memory that's actually still needed by the Wasm side or vise versa. All this adds up to more bookkeeping that developers have to do themselves, which kind of breaks the whole reason to use a managed memory language in the first place. But even if you put all of your objects on one side, on the WebAssembly side, you can't avoid dealing with the JavaScript heap. And that's because of web APIs. Web APIs are specified to accept and return JavaScript objects, which naturally live on the JavaScript heap and are collected by the JavaScript garbage collector. In the original version of WebAssembly, this meant copying your data in both directions between WebAssembly and JavaScript any time you wanted to call a web API. Graphics APIs, like the Dom, Canvas, WebGL, and Web GPU, are especially impacted by this since in some cases, they need to be called hundreds of times per frame or thousands of times per second with very strict latency requirements to avoid user visible jank. The net result is, even after we built a fast compilation target for code, many frameworks and applications ran the risk of producing jankier experiences on the web compared to what they would be able to produce on native mobile platforms. So how do we address this? Well, the WebAssembly community created a new extension that in effect, shares a joint heap between JavaScript and WebAssembly GC modules. Now, your managed memory code can just allocate modules on this joint heap. And when the browser's garbage collector comes around, JavaScript and WebAssembly GC objects are garbage collected together. This means no more bloat. Your WebAssembly module doesn't have to ship its own full garbage collector implementation with your app. And your WebAssembly app can more easily grow or shrink its memory consumption as needed, just like a JavaScript app can. Some browsers, including Chrome, will even return unused WebAssembly memory from this shared heap to the operating system whenever possible, helping ensure all apps running on the user's device remain efficient and responsive. The web API story improves as well. WebAssembly GC modules, create objects in the same heap where the JavaScript Web APIs will look for them, and return values are easily passed back as well, all without excessive copying. So that's WebAssembly GC, smaller binaries for modern, managed memory languages, faster interop with JavaScript code, and the JavaScript-based Web APIs, and a dynamically resizable memory footprint that grows and shrinks to provide your module with what it needs. With WebAssembly GC, the web can finally give a proper welcome to our developer friends building Flutter, Android, and Kotlin multi-platform apps. Let's look at what WebAssembly means for you. Early data shows that WebAssembly GC now runs code compiled from these languages in the browser up to two times faster than compiling them to JavaScript. From a user's point of view, this level of performance is increasingly indistinguishable from what they would see on native mobile platforms. We're talking about apps running at 120 frames per second with single millisecond frame update times. We can now imagine a world where cross-platform frameworks can build apps for native mobile platforms and the web with no perceivable difference in capabilities or performance. And the developer experience gets better too. Previously, developers would have to build separate native Android and iOS apps, as well as a web app to reach the broadest set of users. Cross-platform frameworks, like Kotlin, multi-platform mobile, let developers write their mobile apps business logic, the part that manages user data and implements your apps features, in a single code base that compiles to both Android and iOS, while implementing their user interface using platform native frameworks and widgets. But extending this cross-platform capability to the web ran into some challenges. For a long time, you couldn't really compile mobile languages, like Kotlin, to the web. At best, you could transfer pile it to JavaScript and then run that JavaScript in a browser. This approach produced apps on the web that just weren't as fast and smooth for users as they would be on native mobile platforms. Now, thanks to WebAssemby's new support for managed memory languages, cross-platform apps can compile directly to the native runtime of all three platforms, giving developers access to the reach and instant start up of the web, and giving users a fast and smooth experience wherever they find your app. The Kotlin community also benefits from UI frameworks, like Compose, which can help developers share much of their UI code as well across platforms again, with the performance level matching that of native platforms. Here's Sebastian from JetBrains to share more about Kotlin multi-platform and Compose. Thank you, Vivek. At JetBrains, we think WebAssembly is a promising technology. And we want Kotlin developers to get all the benefits it has to offer. Just recently, we released an experimental version of the WebAssembly target for the Kotlin compiler. SEBASTIAN: We see a lot of potential use cases in Kotlin Wasm's future, from building high-performance web applications running in the browser, to building speedy serverless functions. I want to show you a concrete example of one such thing that is part of the potential future of Kotlin Wasm. So here you can see an application built using Jetpack Compose, the declarative and modern UI framework created by Google for Android. You might have actually seen this specific app before. Now, at JetBrains, we're working on bringing Jetpack Compose to multiple other platforms beside Android, like desktop, iOS, and web. In practice, this means that you can take any knowledge about the APIs of Jetpack Compose that you might have from developing for Android and use it to target other platforms. The web target for Compose is built on top of Kotlin Wasm. It's still experimental. But let me show you what we can already do with it. Here is the same application you just saw on Android running in Google Chrome. It looks and behaves just like we saw on Android before. If we want to get an idea of the current performance of this app, we can open the FPS counter in Chrome's DevTools and watch some of these beautiful animations. We're also working on making it possible for you to debug Kotlin code right inside your browser and inspect variables and stack traces right in Chrome's DevTools using the built-in support for source maps. Now, let's move back to IntelliJ IDEA and take a quick look at the code of our app. As you can see, the UI and business logic of the app are all located in the Common module. It's all code that is shared between the different targets for the project. But we can also specify platform-specific logic for the individual targets in the respective subprojects. That way, we still get to use everything in terms of platform-specific APIs. OK, so after making a small change to our code, we can actually have a look at the result of the changes. And look at that. They appear right in the browser. We hope this little demo made you want to learn more about this experimental technology we're building at JetBrains. If that's the case, follow the link and check out the project sources for this demo yourself. Thank you and take care. VIVEK SEKHAR: Thanks, Sebastian. You can learn more about Kotlin running on the web with WebAssembly at kotlinlang.org. And we're not just making Android apps multi-platform with Kotlin. Multiplatform developers have been using Flutter for years to target Android, iOS, and the web. And on the web, Flutter developers have also had to transpile to JavaScript to run in the browser. But we're unlocking faster performance for Flutter web as well. For the first time this year, compiling Dart code directly to fast and efficient WebAssembly code in the browser. You can read more about the exciting new performance boost offered by Flutter web at flutter.dev/wasm. On the open web, your app is just a click away from new users, who can discover it and share it just as easily as they share a web page, with no stores getting in the way and no revenue split affecting your profitability. The productivity of cross-platform development, the performance of native mobile apps, and the openness of the web-- that's why we love WebAssembly. On behalf of Thomas, myself, the Flutter team, and our friends at JetBrains, thank you so much for joining us. We can't wait to see what you'll build next. [MUSIC PLAYING]
Info
Channel: Google Chrome Developers
Views: 37,106
Rating: undefined out of 5
Keywords: Chrome, Developers, Google, Web, Google I/O, Google IO, IO, I/O, IO 23, I/O 23, Google I/O 23, Google IO 23, Google I/O 2023, Google IO 2023, IO 2023, Google New, Google Announcement, Google Developers, Developer, Development
Id: RcHER-3gFXI
Channel Id: undefined
Length: 22min 3sec (1323 seconds)
Published: Wed May 10 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.