Course contentsShow
← Rust
Lesson 768 of 1,9106. Generics and Static DispatchFree lesson

Generics in WebAssembly Targets

Adapt generic code patterns for memory-constrained WebAssembly execution environments.

In this lesson, you will learn how to leverage Rust’s generic static dispatch to minimize the binary footprint of your WebAssembly (Wasm) modules.

When targeting WebAssembly, the primary constraint is the size of the .wasm binary, as it must be downloaded over the network. Rust’s generics are a double-edged sword here: while they provide powerful abstractions, the compiler generates a unique version of your code for every type used with a generic parameter—a process known as monomorphization.

The Monomorphization Trap

If you use a generic function process<T>(data: T) with twenty different types, the compiler produces twenty distinct machine code implementations. In a Wasm environment, this "code bloat" can significantly inflate your binary size. To combat this, we must balance generic flexibility with binary-conscious design.

Strategy: Prefer Polymorphism for Cold Paths

For frequently called code (hot paths), generics are excellent because static dispatch allows the compiler to inline logic, creating highly optimized Wasm code. However, for "cold paths"—code that is rarely executed, such as error reporting or initialization logic—you can reduce binary size by using dynamic dispatch (&dyn Trait) to force a single implementation:

// Use generics for speed in hot paths
fn process_hot_data<T: DataTrait>(item: T) {
    item.compute(); 
}

// Use trait objects to keep binary size small in cold error paths
fn log_error(item: &dyn DataTrait) {
    console_log!("Error occurred: {}", item.get_id());
}

By choosing &dyn Trait for infrequent operations, you replace multiple monomorphized function variants with a single implementation that uses a vtable. While this introduces a tiny runtime overhead for pointer indirection, it prevents the exponential growth of your WebAssembly binary that occurs when generics are used indiscriminately across your entire codebase.

As you build Wasm modules, treat generic monomorphization as a resource—spend it on performance-critical loops and switch to trait objects when optimizing for module load times and transmission size.

Key Takeaway: Balance your binary size by using static dispatch generics for performance-critical hot paths and trait objects for cold, secondary logic to avoid code bloat in WebAssembly.