Skip to content
All essays
CraftMarch 1, 202511 min

WebAssembly: High-Performance Web Applications

Master WebAssembly. Build near-native performance applications for the web.

Ü
Ümit Uz
Mobile & Full Stack Developer

What is WebAssembly?

Binary instruction format for a stack-based virtual machine. Wasm enables high-performance applications on web pages.

JavaScript:
- Interpreted or JIT compiled
- Dynamic typing
- Garbage collection

WebAssembly:
- Pre-compiled
- Static typing
- Manual memory management
- Near-native performance

Use Cases

  • Games: High-performance game engines
  • Video/Audio: Encoding/decoding
  • Cryptography: Secure algorithms
  • Scientific: Simulations, calculations
  • Legacy: Port C/C++/Rust applications

Hello World (Rust)

Setup

bash
# Install Rust curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh # Add wasm target rustup target add wasm32-unknown-unknown # Install wasm-pack cargo install wasm-pack

Project

rust
// src/lib.rs use wasm_bindgen::prelude::*; #[wasm_bindgen] pub fn greet(name: &str) -> String { format!("Hello, {}!", name) } #[wasm_bindgen] pub fn add(a: i32, b: i32) -> i32 { a + b } #[wasm_bindgen] pub struct Calculator { value: i32, } #[wasm_bindgen] impl Calculator { #[wasm_bindgen(constructor)] pub fn new() -> Calculator { Calculator { value: 0 } } pub fn add(&mut self, n: i32) { self.value += n; } pub fn get_value(&self) -> i32 { self.value } }

Build

bash
# Build wasm package wasm-pack build --target web # Output: # pkg/my_wasm_bg.wasm # WebAssembly binary # pkg/my_wasm.js # JavaScript glue # pkg/my_wasm.d.ts # TypeScript types

JavaScript Integration

html
<!DOCTYPE html> <html> <head> <script type="module"> import init, { greet, add, Calculator } from './pkg/my_wasm.js'; async function run() { await init(); // Simple function console.log(greet('World')); console.log(add(5, 3)); // Class const calc = new Calculator(); calc.add(10); calc.add(5); console.log(calc.get_value()); // 15 } run(); </script> </head> <body> <h1>WebAssembly Demo</h1> </body> </html>

Performance Comparison

javascript
// Fibonacci calculation function fibonacciJS(n) { if (n <= 1) return n; return fibonacciJS(n - 1) + fibonacciJS(n - 2); } // Rust (WebAssembly) #[wasm_bindgen] pub fn fibonacci_wasm(n: i32) -> i32 { if n <= 1 { return n; } fibonacci_wasm(n - 1) + fibonacci_wasm(n - 2) } // Benchmark (fibonacci(40)): // JavaScript: ~1500ms // WebAssembly: ~50ms (30x faster)

Memory Management

rust
use wasm_bindgen::prelude::*; #[wasm_bindgen] pub struct Buffer { data: Vec<u8>, } #[wasm_bindgen] impl Buffer { #[wasm_bindgen(constructor)] pub fn new(size: usize) -> Buffer { Buffer { data: vec ![0; size] } } pub fn write(&mut self, offset: usize, byte: u8) { if offset < self.data.len() { self.data[offset] = byte; } } pub fn read(&self, offset: usize) -> u8 { if offset < self.data.len() { self.data[offset] } else { 0 } } }

React Integration

jsx
import React, { useEffect, useState } from 'react'; import init, { Calculator } from './pkg/my_wasm.js'; function App() { const [calculator, setCalculator] = useState(null); const [value, setValue] = useState(0); useEffect(() => { async function loadWasm() { await init(); setCalculator(new Calculator()); } loadWasm(); }, []); const handleAdd = (n) => { if (calculator) { calculator.add(n); setValue(calculator.get_value()); } }; return ( <div> <p>Value: {value}</p> <button onClick={() => handleAdd(10)}>Add 10</button> <button onClick={() => handleAdd(5)}>Add 5</button> </div> ); }

Optimization Tips

  1. 1Minimize JavaScript-Wasm boundary calls

- Batch operations - Work in Wasm, return result

  1. 1Use appropriate types

- i32/f32 for numbers - Avoid string manipulation in Wasm

  1. 1Linear memory

- Direct memory access for large data - SharedArrayBuffer for parallel processing

  1. 1SIMD

- Single Instruction, Multiple Data - Parallel processing

rust
// SIMD example #[target_feature(enable = "simd128")] pub unsafe fn add_arrays_simd(a: &[f32], b: &[f32], result: &mut [f32]) { let len = a.len(); let chunks = len / 4; for i in 0..chunks { let i = i * 4; let a_simd = v128_load(a.as_ptr().add(i) as *const v128); let b_simd = v128_load(b.as_ptr().add(i) as *const v128); let sum = f32x4_add(a_simd, b_simd); v128_store(result.as_mut_ptr().add(i) as *mut v128, sum); } }

Tools

  • wasm-pack: Build Rust Wasm packages
  • wasm-bindgen: JavaScript-Wasm interoperability
  • wasm-opt: Binary optimizer
  • Wat: WebAssembly Text format (debugging)

Limitations

  • No direct DOM access
  • No garbage collection (manual memory management)
  • JavaScript interop overhead
  • Limited browser support (but improving)

WebAssembly brings near-native performance to the web!

Next essay
Product Analytics: Google Analytics, Mixpanel, Amplitude