KEMBAR78
Building Web Apps with WebAssembly and Blazor | PPTX
Building Web Apps with
WebAssembly and Blazor
Amir Zuker
Senior Software Architect
Founder, Head of Web and Mobile
Twitter: @AmirZuker
For many years now..
JavaScript is the primary runtime
language for web apps..
Demo
Spotify Client
About Me
6
Amir Zuker
 Mentor, leader, architect, developer, instructor, author and speaker
 Over 20 years of experience in the field
 Leads teams and R&D divisions
 Several publications and contributions
 Head of Web and Mobile at CodeValue
Agenda
 Overview
 Portability and how
 Potential impact
 Overview
 Behind the scenes
 Key features
7
WebAssembly
8
WebAssembly (Wasm)
9
"WebAssembly is a binary instruction format for
a stack-based virtual machine.
Wasm is designed as a portable target for
compilation of high-level languages like
C/C++/Rust, enabling deployment on the web
for client and server applications"
https://webassembly.org/
WebAssembly (Wasm)
10
CHOOSE
LANGUAGE
BINARY
FORMAT
NOT ONLY FOR
BROWSERS
PORTABLE PERFORMANCE SECURED
SANDBOXING
Compilation Target for Higher-level Languages
C
C++
Rust
Blazor
Go
…
wasm
Compile to wasm
Wasm can be executed in other technologies too
13
https://hacks.mozilla.org/2018/03/making-webassembly-better-for-rust-for-all-languages/
WebAssembly JavaScript Integration
* By Lin Clark, Till Schneidereit, Luke Wagner - https://mzl.la/2TEUrej
Portable and Interoperable
15
Portable and Interoperable
16https://hacks.mozilla.org/2019/03/standardizing-wasi-a-webassembly-system-interface/?spm=a2c65.11461447.0.0.44244e03zyfYOa
WebAssembly System Interface (WASI) as POSIX
17https://github.com/bytecodealliance/wasmtime/blob/master/docs/WASI-overview.md
Demo
Rust+Wasm
18
WebAssembly System Interface (WASI)
19
Not perfect yet
BUT.. continuing investment
20
Already Used in The Wild..
21
Adobe Lightroom
Autodesk AutoCAD
Unreal Engine
Unity Engine
Quake
Gutenberg post
parser (Rust)
Barcode scanner
22
WebAssembly (Wasm)
 Neither Web nor Assembly, but Revolutionary!
 Not here to replace JavaScript (yet?)
 Key benefits
 Can use a preferred language
 Portable and interoperable
 Compact and performant
Blazor WebAssembly
Browser + Razor = Blazor
23
24
Blazor – In a Nutshell
 A component driven framework
 Build rich web apps using .NET, C# and Razor
 Works on modern browsers
 Interoperable
 Supports SPA, PWA and Server
Blazor Hosting Models
25
- UI interaction and logic runs on server-side
- Leverages web sockets
- Static assets! Runs only in the browser.
- Leverages WebAssembly
Demo
Unboxing:
Blazor WebAssembly
27
What's behind the scenes?
28
Browser Runtime
29
Razor Files
(.razor)
C# Code
(.cs)
Compiled assembly
(.dll)
.NET runtime assemblies
(mscorlib, netstandard, etc.)
3rd party imports
(any .NET standard compliant)
dotnet.wasm
browser version of the mono .NET runtime, compiled to wasm, allows to bootstrap and execute .net standard assemblies
JavaScript interop
blazor.webassembly.js, dotnet.<ver>.js, dom updates, event interceptions, etc.
Browser API's
(DOM updates, event forwarding, canvas, storage, etc.)
Blazor RenderTree
30
https://dzone.com/articles/comparing-native-blazor-components-to-wrapped-java
Blazor Reconciliation
31
https://dzone.com/articles/comparing-native-blazor-components-to-wrapped-java
Much is in the box!
32
Dependency Injection
 Manage services and dependencies
 Control lifetime and scope
33
Authentication / Authorization
34
- Open ID Connect
- OAuth
- Local identities
- Access scopes and claims
- Etc.
Forms and Validation
35
@code
Internationalization
 Manage resource dictionaries
 Supports formatting numbers, dates, etc.
 Sets .NET thread culture to browser setting by default
36
Routing
37
JavaScript Interop
 .NET  JS / JS  .NET
 Use existing libraries or browser API's (mileage may vary)
 Many existing 3rd party packages already fill the gap
 Can do it yourself when needed via JavaScript runtime interop
 Supports static and instance members
38
Progressive Web App (PWA)
 Web app  Native like
 Smooth, immersive
 Push notifications
 Offline support
 Installable
 Includes a built-in PWA template
39
And more!
40
Precompilation
Caching
Dynamic Components
Content Projection
Templates
WebSocket
Http
Data Binding
Events
Parameters (input/props)
Event:Modifiers
Debugging
Code-Sharing
Element References
Cascading Values
Lifecycle Hooks
gRPC-Web
Layouts
Lists+Keys
Configuration
Demo
Interop
41
Blazor – What's Coming
 Component API Enhancements
 Type constraints, required parameters, IAsyncDisposable, SVG, etc.
 CSS isolation
 Hot reloading
 AoT compilation
 Multithreaded runtime
 Lazy loading
42
No .NET products / skillset?
Supporting older browsers?
No additional compute perf? (perhaps)
App-first, bread and butter, limit risk?
Limited tolerance for gaps?
Specific tech? (DICOM, WebGL, GIS, etc.)
Probably not..
Cool Stuff! But Should I?
43
.NET products and skillset? Plus reuse?
Modern browsers?
Additional compute perf? (perhaps)
Tolerate risk?
Tolerate gaps?
No specific tech or ready for short POC's?
Why not?
Maybe?
Resources
 WebAssembly
 https://developer.mozilla.org/en-US/docs/WebAssembly
 https://webassembly.org/
 Blazor
 https://blazor.net
 https://docs.microsoft.com/en-us/aspnet/core/blazor/
 https://github.com/AdrienTorris/awesome-blazor
 Demos
 https://github.com/Spoonbender/wasm-demo
 https://github.com/azuker/blazor-interop
 https://aka.ms/blazor-carchecker
 https://channel9.msdn.com/Events/Build/2020/BOD104
46
Amir Zuker
Senior Software Architect
Founder, Head of Web and Mobile
Twitter: @AmirZuker
Q
A
48
Amir Zuker
Senior Software Architect
Founder, Head of Web and Mobile
Twitter: @AmirZuker

Building Web Apps with WebAssembly and Blazor

Editor's Notes

  • #2 Hello everyone, and welcome to my talk about micro FE First thing first
  • #6 https://caerostris.azurewebsites.net/
  • #7 Senior software architect, instructor, speaker and developer Over 20 years of experience in the field Designed and developed various systems, both backend and frontend Mentored and lead large teams and R&D divisions Publications, e.g. Book: HandsOn Full-Stack Web Development with ASP.NET Core Open source: WCF Contrib WCF Microsoft Official Curriculum (MOC) Head of Web and Mobile at CodeValue
  • #11 A standardized binary code format Not just for browsers! Free to choose your language Cross platform, interoperable and portable Gain better performance (compared to interpreted languages) Secured sandboxing
  • #12 Linear memory – untyped array of bytes. Sandboxed Fast execution – 10% slower than native code, 20× faster parsing Compact – binary around 20% smaller Compile target: The folks working on WebAssembly knew they didn’t want to just support C and C++. They wanted many different languages to be able to compile to WebAssembly. So they needed a language-agnostic compile target. They needed something like the assembly language that things like desktop applications are compiled to—like x86. But this assembly language wouldn’t be for an actual, physical machine. It would be for a conceptual machine. Fast: That compiler target had to be designed so that it could run very fast. Otherwise, WebAssembly applications running on the web wouldn’t keep up with users’ expectations for smooth interactions and game play. Compact: In addition to execution time, load time needed to be fast, too. Users have certain expectations about how quickly something will load. For desktop applications, that expectation is that they will load quickly because the application is already installed on your computer. For web apps, the expectation is also that load times will be fast, because web apps usually don’t have to load nearly as much code as desktop apps. When you combine these two things, though, it gets tricky. Desktop applications are usually pretty large code bases. So if they are on the web, there’s a lot to download and compile when the user first goes to the URL. To meet these expectations, we needed our compiler target to be compact. That way, it could go over the web quickly. Linear memory: But you can’t have a program you downloaded from the web just accessing bytes in memory willy-nilly, using whatever addresses they want. So in order to create a secure way of giving access to memory, like a native program is used to, we had to create something that could give access to a very specific part of memory and nothing else. To do this, WebAssembly uses a linear memory model. This is implemented using TypedArrays. It’s basically just like a JavaScript array, except this array only contains bytes of memory. When you access data in it, you just use array indexes, which you can treat as though they were memory addresses. This means you can pretend this array is C++ memory.
  • #14 Although it was intended for high performant web apps, it is an open standard You can see more and more platforms supporting executing Wasm Can be used in other technologies given proper bindings (glue) But now that native module support is in browsers, we can add a declarative API. Specifically, we can use the ES module API. With this, working with WebAssembly modules should be as easy as importing them: import { myFunc } from 'myModule.wasm'; https://hacks.mozilla.org/2018/03/making-webassembly-better-for-rust-for-all-languages/
  • #15 Fast calls – 2017, minimal support. Already implemented in most browsers Data Exchange – WebAssembly supports only numbers, interaction via serialization to linear memory Proposal Module Integration – Module integration with JS Proposal Toolchain Integration - webpack Plugin wasm-pack Backward compatibility - wasm2js
  • #16 V8 can execute wasm through a compiler. Used TurboFan – very efficient, took a long time though, affected apps that used (e.g. AutoCad) Now uses LiftOff+TurboFan – faster liftoff compilation, optimize critical paths by compiling it with turbofan https://v8.dev/blog/liftoff Istio – inbound http filters using Proxy WASM on top of V8 AS - AssemblyScript compiles a strict variant of TypeScript (basically JavaScript with types) to WebAssembly using Binaryen. It generates lean and mean WebAssembly modules while being just an npm install away WASM on k8s – Krustlet Although it was intended for high performant web apps, it is an open standard You can see more and more platforms supporting executing Wasm Can be used in other technologies given proper bindings (glue) But now that native module support is in browsers, we can add a declarative API. Specifically, we can use the ES module API. With this, working with WebAssembly modules should be as easy as importing them: import { myFunc } from 'myModule.wasm'; https://hacks.mozilla.org/2018/03/making-webassembly-better-for-rust-for-all-languages/
  • #17 Create portable binaries
  • #18 https://github.com/bytecodealliance/wasmtime/blob/master/docs/WASI-overview.md A standardized API, set of functions, "syscalls" Portable System Interface for WebAssembly WASI is being designed from the ground up for WebAssembly, with sandboxing, portability, and API tidiness in mind, making natural use of WebAssembly features such as i64, import functions with descriptive names and typed arguments, and aiming to avoid being tied to a particular implementation. We'll often call functions in these APIs "syscalls", because they serve an analogous purpose to system calls in native executables. However, they're just functions that are provided by the surrounding environment that can do I/O on behalf of the program. WASI is starting with a basic POSIX-like set of syscall functions, though adapted to suit the needs of WebAssembly, such as in excluding functions such as fork and exec which aren't easily implementable in some of the places people want to run WebAssembly, and such as in adopting a capabilities-oriented design. And, as WebAssembly grows support for host bindings and related features, capabilities can evolve to being represented as opaque, unforgeable reference typed values, which can allow for finer-grained control over capabilities, and make the API more accessible beyond the C-like languages that POSIX-style APIs are typically aimed at To facilitate use of the WASI API, a libc implementation called WASI libc is being developed, which presents a relatively normal musl-based libc interface, implemented on top of a libpreopen-like layer and a system call wrapper layer (derived from the "bottom half" of cloudlibc). The system call wrapper layer makes calls to the actual WASI implementation, which may map these calls to whatever the surrounding environment provides, whether it's native OS resources, JS runtime resources, or something else entirely. This libc is part of a "sysroot", which is a directory containing compiled libraries and C/C++ header files providing standard library and related facilities laid out in a standard way to allow compilers to use it directly. With the LLVM 8.0 release, the WebAssembly backend is now officially stable, but LLVM itself doesn't provide a libc - a standard C library, which you need to build anything with clang. This is what the WASI-enabled sysroot provides, so the combination of clang in LLVM 8.0 and the new WASI-enabled sysroot provides usable Rust and C compilation environments that can produce wasm modules that can be run in Wasmtime with WASI support, in browsers with the WASI polyfill, and in the future other engines as well.
  • #20 One of the hindrances of using WebAssembly outside browser environments has been the lack of a single compile target. But last year Mozilla announced the WebAssembly System Interface effort, or WASI, to provide a system interface so that compilers can target the interface and not the underlying operating system – and that could make WebAssembly a developer target at scale Solomon Hykes is the Founder, Chief Technology Officer and Chief Architect of Docker and the creator of the Docker open source initiative https://cloudblogs.microsoft.com/opensource/2020/04/07/announcing-krustlet-kubernetes-rust-kubelet-webassembly-wasm/ https://hacks.mozilla.org/2019/03/standardizing-wasi-a-webassembly-system-interface/?spm=a2c65.11461447.0.0.44244e03zyfYOa Get ready for a lot of acronyms. WebAssembly – commonly called WASM –  is a compact bytecode format optimized for fast download and maximum execution speed and has been an open web standard for a few years. Up until now, it has been used mainly in browsers for fully sandboxed, but highly performant, computing. For one recent example, Microsoft’s Blazor Framework can use WASM to enable very performant and complex visualizations, among other things. One of the hindrances of using WebAssembly outside browser environments has been the lack of a single compile target. But last year Mozilla announced the WebAssembly System Interface effort, or WASI, to provide a system interface so that compilers can target the interface and not the underlying operating system – and that could make WebAssembly a developer target at scale. If you want to know a lot more about WASI, Lin Clark’s original announcement is a great explainer. Importantly, at a very high level WASM has two main features that the Kubernetes ecosystem might be able to use to its advantage: WebAssemblies and their runtimes can execute fast and be very small compared to containers WebAssemblies are by default unable to do anything; only with explicit permissions can they execute at all These two features hit our sweet spot, which suggested to us that we might profitably use WASM with Kubernetes to work in constrained and security-conscious environments – places where containers have a harder time.
  • #21 https://www.fastly.com/blog/how-fastly-and-developer-community-invest-in-webassembly-ecosystem As all these changes were underway, we quickly determined that a C header was not the most universal way to specify the standard. We needed something more flexible and expressive that could work with the huge variety of programming languages that were targeting WebAssembly. And, most importantly, we needed to enable code generation to take care of the tedious, error-prone, and security-critical work of maintaining the very lowest-level implementations of an evolving standard. That’s where the witx file format comes in, which is a machine-readable description of the WASI standard Witx is now used to generate both interfaces to, and implementations of, the WASI standard for several programming languages Meanwhile, wig and wiggle are two generations of automated tooling related to witx. wig served as the first attempt at using witx inside wasi-common, while wiggle — a successor to wig that now powers wasi-common — offers better ways of handling security properties. Both witx and wiggle are taking incremental steps toward implementing the WebAssembly interface types proposal, which will make Wasm even more powerful and portable. Interface types will make it seamless for a WebAssembly module to interoperate with different environments using rich APIs and complex types such as arrays, objects, and strings — without requiring any glue code or extra build steps
  • #22 eBay barcode scanner – 50FPS vs 1FPS (scans per seconds), 95% vs 20% success rate Wordpress Gutenberg post parser RUST-based – 96% - 317% parsing speed increase
  • #23 Interoperable - JS to Blazor / Blazor to JS Can reuse existing JS libraries (mileage may vary)
  • #25 Interoperable - JS to Blazor / Blazor to JS Can reuse existing JS libraries (mileage may vary)
  • #26 Blazor server: Released with .NET core 3.0, around 7 months ago UI updates are handled on the server-side ..and changes are reconciled on the client-side Leverages web sockets and SignalR Minimize load time and load on the client Increases latency, unstable connection is a problem Blazor wasm: Released almost 2 months ago Static assets Executed only on the browser Leverages WebAssembly
  • #28 Visual Studio for Windows/Max dotnet CLI for any platform Can install Blazor template: dotnet new -i Microsoft.AspNetCore.Blazor.Templates dotnet new blazorwasm –o MyApp cd MyApp dotnet run
  • #30 dotnet.wasm .NET runtime compiled to WebAssembly so it can run inside browsers MyApp.dll Regular real .NET dlls that can be loaded and run inside the dotnet runtime wasm https://weblog.west-wind.com/posts/2018/jul/31/web-assembly-and-blazor-reassembling-the-web But even more interesting than performance is the possibility of using Web Assembly to bootstrap higher level runtimes that can then execute higher level languages like .NET code. This is exactly the approach that Microsoft's Blazor framework takes. Blazor uses a Mono compiled version of the .NET Runtime compiled to a WASM module to execute .NET Standard 2.0 code as shown in Figure 2. mono.wasm is a browser customized version of the Mono .NET Runtime compiled to Web Assembly WASM module that allows for bootstrapping .NET Standard assemblies and execution of .NET code. Blazor then sits on top of this core runtime and implements the Razor engine which is used as an entry point to the .NET Code that can be processed inside of Razor pages. In addition Blazor also supports JavaScript -> .NET and .NET -> JavaScript Interop by way of the Blazor JavaScript framework's system features. Using the Mono + Blazor in this way you can do most of the things you normally do in .NET such as importing and referencing additional .NET Standard assemblies and instantiate classes and execute code in them. Currently Blazor uses Mono as an interpreter of .NET code which essentially allows loading and execution of .NET DLL assemblies. Rather than compiling every bit of .NET code your application runs to WASM, only the Mono Runtime is a pre-compiled WASM module. Mono then handles the execution of all .NET code loaded from these .NET Standard assemblies. This all sounds incredibly complicated, but from the developer perspective of building an application, the process is actually surprisingly simple: You create Razor pages and components with C# code inside of them and it just works the way you would expect it to. Blazor hides the complexity of the runtime bootstrapping and .NET code execution, and provides a familiar .NET and Razor Pages like development experience that runs entirely inside of the Browser on the client side! You can even reference your own or third party assemblies via NuGet and take advantage of a large chunk of .NET CLR functionality. It's pretty impressive to see this work.
  • #31 RenderTree – HTML DOM Abstraction Child Components and Templates are component properties with a special class called a RenderFragment (a delegate that writes the content to a RenderTreeBuilder) Child components are extremely powerful as they can transform component behavior or composition of components. Allows dynamic components, content projection and templates <TelerikTabStrip> @foreach (var f in Forecasts) { <TelerikTab Title=@f.City> <Weather City=@f.City TempC=@f.Temp Forecast=@f.Outlook> </Weather> </TelerikTab> } </TelerikTabStrip> Blazor framework's component architecture and use of RenderFragments allows Blazor to declare components in this way
  • #32 RenderTree – HTML DOM Abstraction Child Components and Templates are component properties with a special class called a RenderFragment (a delegate that writes the content to a RenderTreeBuilder) Child components are extremely powerful as they can transform component behavior or composition of components. Allows dynamic components, content projection and templates <TelerikTabStrip> @foreach (var f in Forecasts) { <TelerikTab Title=@f.City> <Weather City=@f.City TempC=@f.Temp Forecast=@f.Outlook> </Weather> </TelerikTab> } </TelerikTabStrip> Blazor framework's component architecture and use of RenderFragments allows Blazor to declare components in this way
  • #35 Can choose to set up authorization against your backend server when creating the app If you do that, users will be stored in your own database on the backend Supports also Open ID Connect, Google, Facebook, etc.
  • #36 https://dzone.com/articles/comparing-native-blazor-components-to-wrapped-java
  • #37 DI – ".AddLocalization" – give resource provider (IStringLocalizer) Razor @inject IStringLocalizer<App> Localizer <p>@Localize["Enter license number"]</p> App – resource type (resx file – App.resx / App.es.resx) Automatically sets .net thread culture to browser setting Automatically supports formatting numbers, dates, etc.
  • #39 .NET -> JS / JS -> .NET Use JS Browser/DOM API or third party Let someone else do it for you, look for an existing nuget package Mind the gap, might need to do yourself (e.g. IndexedDb) Put .js file in your wwwroot window.localVideoStore Use JS Interop API's in .NET: ValueTask<Vehicle[]> Do() { return js.InvokeAsync<Vehicle[]>("localVideoStore.getAll", "localedits"); } Can create a .NET wrapper and plug it into the DI
  • #40 Own separate window, without the browser chrome, launch from start menu Enable offline by default only for published apps only, not development PWA – downloads new versions asynchronously Develop – should always work on latest dotnet publish -c Release cd bin\Release\netcoreapp3.1\public dotnet CarChecker.Server.dll
  • #41 material, bootstrap, ant, devexpress, Telerik, redux, mobx, etc. Event modifiers (like vuejs) - @onpointerdown:stopPropagation Code sharing Share code on the frontend and backend .NET products Standard class library as a shared assembly NuGet packages Debugging Debug .net code running on webassembly, including JS (wwwroot), and server Fullstack debugging in a single session Can use browser dev tools and vscode Blazor caches files automatically as much as it can Precompressed framework files
  • #42 Visual Studio for Windows/Max dotnet CLI for any platform dotnet new blazorwasm –o MyApp cd MyApp dotnet run
  • #43 Traditionally it’s not been possible to use gRPC from browser-based applications, because gRPC requires HTTP/2, and browsers don’t expose any APIs that let JS/WASM code control HTTP/2 requests directly. But there is a solution! gRPC-Web is an extension to gRPC which makes it compatible with browser-based code (technically, it’s a way of doing gRPC over HTTP/1.1 requests). gRPC-Web hasn’t become prevalent yet because not many server or client frameworks have offered support for it… until now.
  • #44 CodeSharing Share code on the frontend and backend .NET products Standard class library as a shared assembly NuGet packages
  • #45 Visual Studio for Windows/Max dotnet CLI for any platform dotnet new blazorwasm –o MyApp cd MyApp dotnet run
  • #48 Alright, that's a wrap! Thank you all for listening, I had a blast Enjoy the rest of the conference, and happy coding
  • #50 Alright, that's a wrap! Thank you all for listening, I had a blast Enjoy the rest of the conference, and happy coding