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 performanceUse 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-packProject
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 typesJavaScript 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
- 1Minimize JavaScript-Wasm boundary calls
- Batch operations - Work in Wasm, return result
- 1Use appropriate types
- i32/f32 for numbers - Avoid string manipulation in Wasm
- 1Linear memory
- Direct memory access for large data - SharedArrayBuffer for parallel processing
- 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!