WebAssembly for Beginners – Part 2: Goals, Key Concepts, and Use Cases

In my previous post on WebAssembly for Beginners – Part 1, I introduced WebAssembly (WASM) and discussed its background, capabilities, roadmap, and relationship with JavaScript. In this second installment, I‘ll dive deeper into WASM‘s goals, explain its key concepts, review additional use cases, and highlight some real-world examples. My aim is to provide a comprehensive understanding to help you evaluate if and how WebAssembly could be useful for your applications.

Recap: What is WebAssembly?

Before jumping into goals and concepts, let‘s quickly recap what WebAssembly actually is for those just joining…

WebAssembly (WASM) is a low-level bytecode format that can be executed at near-native speeds in web browsers. It works by compiling source code written in languages like C/C++, Rust, Zig and others into a size- and load-time efficient binary format. The key value of WebAssembly is it unlocks performance critical applications on the web by removing the performance penalty of languages like JavaScript.

Browser support for WebAssembly is excellent, with all major browsers now providing support including Chrome, Firefox, Safari, MS Edge. Apple in particular is planning to make extensive use of WASM to boost Safari performance.

Goals of WebAssembly

WebAssembly has the following primary design goals:

1. Performance

A key goal is to enable near-native computational performance for web applications. The compact module format significantly reduces load times and the low-level binary execution reduces interpretation overhead.

This makes it feasible to run everything from 3D games to video editing software in the browser at full speed. Early benchmarks comparing C/C++ versus JavaScript code showed massive performance gains from 5x-15x faster. And improvements in WebAssembly compilers is further expanding this performance lead.

2. Leverage Hardware Capabilities

In addition to general computational performance, WebAssembly aims to provide low-overhead access to client hardware capabilities. This includes features like SIMD vector instructions for parallel math processing in CPUs as well as newer proposals around access to GPU, tensor and machine learning hardware acceleration.

The goal is to remove abstraction layers to truly tap into the immense raw capability of modern hardware, both mobile and desktop.

3. Integrate Well With Existing Web

Rather than reinvent browser programming models, WebAssembly aims to integrate cleanly with existing web technologies. It is designed to complement rather than replace JavaScript. Interoperability mechanisms allow fluid data and function calling between JavaScript and WebAssembly code.

This ensures WebAssembly can accelerate portions of existing apps rather than requiring whole scale rewrites. It also ensures compatibility with years of tooling, libraries and best practices around web development.

4. Work With Browser Security Models

Web platform security policies like same-origin access control are critical for the web‘s security. WebAssembly doesn‘t aim to change these models but rather work within them. By only allowing controlled access to underlying hardware based on origin permissions, it ensures these security boundaries are maintained.

5. Support Non-Browser Environments

Although the initial focus is Browser usage, WebAssembly is designed to work in other environments including serverless functions, edge computing, CDNs and more. Compiler toolchains support both browser and non-browser WASM module variants.

6. Provide Good Developer Experience

Finally, WebAssembly aims to support high developer productivity with readable text format, error messaging, and toolchain integration with popular compilers and IDEs.

Combined, these goals show WebAssembly‘s aim to become the assembly language of the web – high performance yet approachable, safely integrated yet extensible across environments.

Key Concepts

Underlying WebAssembly‘s goals, the core technical design includes the following key concepts:

WebAssembly Module Format

The foundation of WebAssembly is its modular binary format. Text-based source code gets compiled into compact, efficient bytecode that loads much faster than formats like JSON or XML. It also streams efficiently allowing execution to start before entire module is loaded.

Memory Model

WASM uses a memory model with an ever expandable linear address space. Data segments, function stacks, etc. map into this shared memory. The memory size starts small but can grow to GB scale or further. Fine grained memory access opcodes allow both high performance and safe access.

Type System

For safety and tooling, the format incorporates a type system including basics like i32/i64/f32/f64 plus support for contracts around security and portability. Value types describe data while reference types handle functions, arrays, etc.

Stack Machine Execution

Code itself is expressed in terms of a register based virtual Instruction Set Architecture leveraging a stack machine. This provides a good balance of code density vs ease of decoding. The ISA is designed to map cleanly to typical hardware capabilities.

Compiler Pipeline

Rather than require developers to write directly at the bytecode level, WebAssembly relies on compiler toolchains to convert higher level languages into WASM modules. This allows leveraging existing languages while still delivering performance gains.

JavaScript Integration

Instead of living on its own, WebAssembly interoperates closely with JavaScript. Calls can go in both directions allowing flexibility in what runs where. A JS developer needing acceleration can offload select functions to compiled WASM.

Together these concepts enable WebAssembly to deliver on its goals around performance, safety, and interoperability in a unified way.

Expanded Use Cases

In my previous post, I touched briefly on the types of applications that can benefit from WebAssembly. Here I will expand further on promising use cases:

Gaming

Game engines like Unity support exporting games to WebAssembly enabling stunning graphics fully in browser. Studios like PlayCanvas use WASM to bring high quality games to both desktop and mobile web.

Computer Vision

Performance sensitive OpenCV vision processing pipelines can run client-side unlocking AR experiences. WASM cam also speed up model inference – for example face detection demo.

Data Visualization

Charts with tens of thousands of data points can render smoothly. Libraries like Plotly integrate WebAssembly based rendering for 60fps visualization of streaming data. Financial data dashboards see lift.

Speech Recognition

Tools like Mozilla‘s DeepSpeech show how WebAssembly delivers low latency speech processing entirely on device rather than round-tripping to the cloud.

Machine Learning

Tensorflow, PyTorch and other ML libraries compile to WASM opening localized ML inferencing. Edge impulse demonstrates keyword spotting running efficiently on low power devices.

And this is just a subset – usage spans from encryption to compression to databases and more. As compiler coverage continues improving, so will the use cases.

Code Examples

To make usage more concrete, let‘s look at some code examples…

First, a simple C function:

int add(int a, int b) {
  return a + b;
}

Compiled via Emscripten toolchain to WebAssembly wrapping in JavaScript:

WebAssembly.instantiate(wasmCode, imports).then(function(instance) {
  let add = instance.exports.add;

  let sum = add(1, 2);
});

And similarly calling from Rust:

#[no_mangle]
pub extern fn add(x: i32, y: i32) -> i32 {
  x + y  
}
let imports = {
  env: {
    add: (x, y) => add(x, y)
  }
};

let instance = await WebAssembly.instantiate(wasmCode, imports);

let sum = instance.exports.add(1, 2);

Performance Benchmarks

But does WebAssembly actually deliver on its performance goals in practice? Yes – benchmarks demonstrate massive gains…

{{ Insert WASM benchmarks perf table or graphs showing 5-15x JavaScript speedup with links }}

As compilers and hardware improve, this performance delta grows over time.

Development Toolchain

To boost productivity, an ecosystem of WebAssembly tools has emerged including:

Compilers

  • Emscripten – LLVM based compiler targeting WebAssembly
  • AssemblyScript – TypeScript to WASM transpiler
  • Blazor – .NET runtime using WebAssembly
  • Rust, Zig and other languages

Runtimes

  • Wasmer – Universal runtime for executing WASM modules
  • Wasmtime – High performance runtime focused on modularity
  • Lucet – Runtime focused on extremely fast startup

IDEs

  • WebAssembly Studio – In browser IDE + toolkit
  • VSCode – Extension for authoring .wat and integrating with toolchains

And many more open source and commercial tools that improve the developer experience.

Building an Application

To make this fully concrete, let‘s walk through building a WebAssembly application from scratch…

We‘ll compile a C based project to WASM step-by-step:

  1. Write application logic in C
  2. Compile to WASM module using Emscripten
  3. Generate JS bindings
  4. Hydrate into Web page
  5. Call WebAssembly functions from JavaScript

1. C Application Logic

// math.c
int add(int x, int y) {
  return x + y; 
}

Simple function but illustrates the process.

2. Compile to WebAssembly

emcc math.c -o math.wasm -O3 -s MODULARIZE=1 -s ‘EXPORT_NAME="createMath"‘  

This uses Emscripten toolkit to compile to a WASM module with exports.

3. Generate JS Bindings

emcc --bind math.c -o math.js

Creates JavaScript glue code for interfacing.

4. Hydrate HTML Page

<html>
  <body>
    <script src="math.js"></script>
    <script>
      WebAssembly.instantiateStreaming(fetch(‘math.wasm‘), createMath).then(...); 
    </script>
  </body>
</html>

Loads WASM async and glues it together.

5. Call WASM From JavaScript

let instance = await WebAssembly.instantiate(...);

let add = instance.exports.add;

let sum = add(1, 2); // 3

And we have a WebAssembly app ready to go!

The toolchains handle complexities like generating bindings and wiring everything up across runtimes.

Emerging Best Practices

As developer experience with WebAssembly matures, some best practices have started solidifying:

  • Start by porting performance sensitive code rather than entire apps
  • Profile first to identify hot functions instead of guessing
  • Explicitly manage size budgets to keep downloads small
  • Precompile assets like game sprites to avoid runtime cost
  • Consider breaking code into multiple modules that can be lazy loaded
  • Follow emerging standards like Web IDL bindings to ease interfaces
  • Polyfills smooth browser differences during early adoption

More will emerge but these form a solid starting point.

Additional Examples

Beyond the samples above, many impactful real-world applications leverage WebAssembly:

Figma

The popular browser based design tool Figma uses WebAssembly to accelerate performance throughout their app – improving initialization, UI rendering and file processing.

Epic Games

AAA games studio Epic Games ports complex titles like AutoChess to the browser using WebAssembly allowing full featured gaming with no installs.

Microsoft Azure

Azure‘s platform leverages WebAssembly widely from IoT edge modules to microbiome sequencing analysis demos, showcasing versatile cloud usage.

The applications are expansive and growing daily as awareness spreads.

Alternatives

WebAssembly isn‘t the only option for boosting web application performance. Let‘s compare it to some alternatives:

asm.js

Asm.js served as an intermediate step towards WebAssembly. It showed the promise of compiling C/C++ to highly optimized JavaScript. But WebAssembly‘s binary format unlocks much better performance and a sleeker developer experience.

Native Apps

Native desktop and mobile apps enable full access to device capabilities and thus maximum performance. But they come at a cost of much larger downloads, weaker portability, and poor cross-device distribution.

Cloud Offloading

Shifting processing to server side through containers, functions and services can utilize massive cloud infrastructure. But this incurs latency, privacy and connectivity requirements.

Overall WebAssembly hits a sweet spot between power and accessibility – offering native runtime performance yet with the low friction distribution of the web.

Limitations

For balance, we should still acknowledge some current limitations around WebAssembly:

  • Browser differences in full support
  • Additional toolchain complexity vs pure JavaScript
  • Code size overheads if not careful
  • Multi-threading support still nascent
  • Not suitable for every problem (use judiciously)

So while compelling it isn‘t a silver bullet either. Combined strategically with other techniques, it can magnify what the web makes possible.

What‘s Next for WebAssembly

WebAssembly continues evolving rapidly. The roadmap highlights active proposals around:

  • Support for additional languages
  • Expanded APIs granting more system access
  • Garbage collection integrations
  • Multi-threading capabilities
  • SIMD and other hardware acceleration integrations

Together these will increase both the ease of use and performance potential.

And likely surface yet more applications we can‘t even envision today, as compilers catch up with the possibilities.

Conclusion

I hope this piece gives a much more thorough introduction to WebAssembly. We covered goals around high performance, safe integration, broad applicability and good developer experience.

We dove deeper into both key concepts like the modular format and execution model as well as expanded use cases highlighting where WebAssembly unlocks innovation across domains.

Real-world examples showcase impressive in-production usage with early best practices emerging. The technology continues rapidly improving too in capabilities.

There‘s never been a better time to start building using WebAssembly. Used judiciously, it enables levels of user experience in the browser that could previously only be dreamed of. Unleash your creativity to take advantage of this tremendous advance!

I‘m excited to see what you build. Ping me @user or via our website if you have any other questions.