WebAssembly (WASM) startede som en made at kore C++ i browseren. I 2026 korer det overalt - browsere, servere, edge-netvaerk, indlejrede enheder - og driver nogle af de mest kraevenede applikationer pa nettet. Figmas rendering-motor, Adobe Photoshop pa nettet, Google Meets videobehandling og Cloudflares edge-compute-platform korer alle pa WebAssembly.
Chrome Platform Status angiver WASM til cirka 5,5 % af alle Chrome-sideindlaesninger i begyndelsen af 2026, op fra 4,5 % aret for. Med WASM 3.0 som W3C-standard og WASI pa vej mod version 1.0 har okosystemet naet et vendepunkt.
Denne guide daekker alt, du skal vide for at begynde at bygge med WebAssembly.
Hvad er WebAssembly?
WebAssembly er et binaert instruktionsformat designet som kompileringsmal. Du skriver kode i et hojniveausprog (Rust, C, C++, Go, Kotlin), kompilerer det til .wasm og korer det i ethvert miljo, der har en WASM-runtime - browsere, Node.js, Cloudflare Workers, Wasmtime eller Wasmer.
Hvordan det virker
WASM er en stakbaseret virtuel maskine. Funktioner skubber vaerdier pa en operandstk og fjerner dem igen. Vaerts-runtime:en (V8 i Chrome, SpiderMonkey i Firefox) JIT-kompilerer WASM-bytekoden til nativ maskinkode, hvilket er grunden til, at ydeevnen er naesten nativ.
Vigtige egenskaber:
- Sandboxet eksekvering: WASM-moduler kan kun fa adgang til ressourcer, som vaerten eksplicit giver. Intet filsystem, intet netvaerk, ingen OS-adgang medmindre det er tilladt. Dette er fundamentalt anderledes end nativ kode.
- Lineaer hukommelse: en enkelt sammenhaengende
ArrayBuffer, der deles mellem WASM og vaerten. Komplekse data (strenge, structs) sendes ved at skrive til hukommelsen og dele en pointer. - Typebegraenset: WASM understotter nativt kun fire typer:
i32,i64,f32,f64. Alt andet (strenge, arrays, objekter) kraever kodning via lineaer hukommelse eller Component Model. - Portabelt: den samme
.wasm-binaerfil korer pa enhver platform med en WASM-runtime, uden rekompilering.
WASM vs JavaScript
WASM erstatter ikke JavaScript. Det supplerer det.
| Aspekt | JavaScript | WebAssembly |
|---|---|---|
| Parsing | Parse + kompiler ved korsel | Praekompileret binaerfil, kun afkodning |
| Eksekveringshastighed | JIT-optimeret, variabel | Naesten nativ, konsistent |
| Opstartstid | Hurtig for sma scripts | Hurtig afkodning, forudsigelig |
| DOM-adgang | Direkte | Indirekte (via JS-gluekode) |
| Bedst til | UI, DOM-manipulation, event-handtering | CPU-intensive beregninger |
| Garbage collection | Indbygget | WasmGC (ny) eller manuel |
Brug JavaScript til UI- og DOM-arbejde. Brug WASM til tunge beregninger: billedbehandling, videokodning, fysiksimulationer, kryptografi, databehandling.
WASM 3.0: hvad er nyt
WebAssembly 3.0 blev en W3C-standard i september 2025 og standardiserede ni funktioner, der havde vaeret under udvikling i arevis.
| Funktion | Hvad den muliggor |
|---|---|
| WasmGC | Nativ garbage collection i WASM. Styrede sprog (Java, Kotlin, Dart) kan kompilere til WASM uden at medbringe deres egen GC-runtime. Understottet i Chrome 119+, Firefox 120+, Safari 18.2+. |
| Exception Handling | Nativt try/catch i WASM. Tidligere kraevede exceptions dyre rundture til JavaScript. |
| Tail Calls | Muliggor effektiv rekursion uden stack overflow. Afgurende for funktionelle sprog. |
| Relaxed SIMD | 128-bit vektorinstruktioner til parallel databehandling. Muliggor hardwarespecifikke optimeringer. |
| Memory64 | Bryder gennem 4 GB-graensen for lineaer hukommelse. Nodvendigt for storskala databehandling. |
| Multi-memory | Flere uafhaengige hukommelsesregioner i et modul. |
Den mest virkningsfulde er WasmGC. Tidligere betod kompilering af Java eller Kotlin til WASM, at man sendte en hel garbage collector som en del af binaerfilen, hvilket opblaste filstorrelserne. Nu handler browserens egen GC hukommelsesstyringen for WASM-moduler, lige som den gor for JavaScript.
WASI: WebAssembly ud over browseren
WASM i browseren er kraftfuldt, men WASI (WebAssembly System Interface) er det, der gor WASM til en universel runtime. WASI leverer standardiserede graenseflader for systemressourcer - filer, netvaerk, ure, tilfaeldige tal - og muliggor, at WASM-moduler kan kore uden for browseren.
WASI Preview 2 (den nuvaerende stabile udgivelse) definerer disse graenseflader:
wasi:filesystem- filoperationer via capability-handles (ikke traditionelle fildeskriptorer)wasi:sockets- TCP/UDP-netvaerkwasi:http- HTTP-request/response-handteringwasi:clocks- vaegur, monotont urwasi:random- kryptografisk tilfaeldighedwasi:cli- kommandolinjeargumenter, miljovariabler, stdio
Nogleprincippet er capability-baseret sikkerhed: et WASM-modul kan ikke fa adgang til filsystemet, medmindre vaerten eksplicit giver et handle til en specifik mappe. Dette gor WASI fundamentalt sikrere end at kore native eksekverbare filer.
Vejen til WASI 1.0
WASI 0.3.0 (med tilfoejelse af async/concurrency-primitiver) forventes i 2026, med WASI 1.0 derefter. Den vigtigste nyhed er sprogintegreret async med zero-copy streaming I/O.
Component Model
Kerne-WASM-moduler kan kun udveksle tal. Component Model loser denne begraensning ved at tilfoeje et rigt typesystem og et kompositionslag oven pa WASM.
WIT (WebAssembly Interface Types)
WIT er et Interface Definition Language, der lader komponenter deklarere deres imports og exports med rige typer - strenge, records, lister, varianter, enums - ikke kun i32 og f64.
// calculator.wit package myorg:calculator@1.0.0; interface operations { record calculation { expression: string, result: f64, timestamp: u64, } add: func(a: f64, b: f64) -> f64; multiply: func(a: f64, b: f64) -> f64; history: func() -> list<calculation>; } world calculator { export operations; }
Toolchains som wit-bindgen genererer sprogspecifikke bindings fra WIT-filer. En Rust-komponent og en Python-komponent kan udveksle strenge, records og lister gennem WIT-kontrakter, uden at nogen af siderne behover at kende den andens implementeringssprog.
Byg dit forste WASM-modul med Rust
Rust har den mest modne WASM-tooling. Lad os bygge et praktisk eksempel: et billedbehandlingsmodul, der korer i browseren.
Setup
# Install the WASM target for Rust rustup target add wasm32-unknown-unknown # Install wasm-pack (builds Rust to WASM + generates JS bindings) cargo install wasm-pack # Create a new library project cargo new --lib image-processor cd image-processor
Konfigurer Cargo.toml
[package] name = "image-processor" version = "0.1.0" edition = "2021" [lib] crate-type = ["cdylib"] [dependencies] wasm-bindgen = "0.2"
Skriv Rust-koden
// src/lib.rs use wasm_bindgen::prelude::*; /// Convert an image buffer to grayscale. /// Input: RGBA pixel data as a flat u8 array (4 bytes per pixel). /// Output: Modified in place for zero-copy performance. #[wasm_bindgen] pub fn grayscale(pixels: &mut [u8]) { for chunk in pixels.chunks_exact_mut(4) { let r = chunk[0] as f32; let g = chunk[1] as f32; let b = chunk[2] as f32; // ITU-R BT.709 luminance coefficients let gray = (0.2126 * r + 0.7152 * g + 0.0722 * b) as u8; chunk[0] = gray; chunk[1] = gray; chunk[2] = gray; // chunk[3] is alpha, leave unchanged } } /// Adjust brightness of an image. /// factor > 1.0 brightens, < 1.0 darkens. #[wasm_bindgen] pub fn adjust_brightness(pixels: &mut [u8], factor: f32) { for chunk in pixels.chunks_exact_mut(4) { chunk[0] = ((chunk[0] as f32 * factor).min(255.0)) as u8; chunk[1] = ((chunk[1] as f32 * factor).min(255.0)) as u8; chunk[2] = ((chunk[2] as f32 * factor).min(255.0)) as u8; } } /// Invert all colors in the image. #[wasm_bindgen] pub fn invert(pixels: &mut [u8]) { for chunk in pixels.chunks_exact_mut(4) { chunk[0] = 255 - chunk[0]; chunk[1] = 255 - chunk[1]; chunk[2] = 255 - chunk[2]; } } /// Calculate the average brightness of an image (0-255). #[wasm_bindgen] pub fn average_brightness(pixels: &[u8]) -> f32 { let mut total: f64 = 0.0; let pixel_count = pixels.len() / 4; for chunk in pixels.chunks_exact(4) { let luminance = 0.2126 * chunk[0] as f64 + 0.7152 * chunk[1] as f64 + 0.0722 * chunk[2] as f64; total += luminance; } (total / pixel_count as f64) as f32 }
Build
wasm-pack build --target web
Dette producerer en pkg/-mappe med:
image_processor_bg.wasm- den kompilerede WASM-binaerfilimage_processor.js- JavaScript-gluekode med TypeScript-definitionerpackage.json- klar til publicering pa npm
Brug i JavaScript
<!DOCTYPE html> <html> <head><title>WASM Image Processor</title></head> <body> <canvas id="canvas" width="800" height="600"></canvas> <button onclick="applyGrayscale()">Grayscale</button> <button onclick="applyBrightness()">Brighten</button> <button onclick="applyInvert()">Invert</button> <script type="module"> import init, { grayscale, adjust_brightness, invert } from "./pkg/image_processor.js"; let ctx; let imageData; async function setup() { await init(); const canvas = document.getElementById("canvas"); ctx = canvas.getContext("2d"); // Load an image onto the canvas const img = new Image(); img.onload = () => { ctx.drawImage(img, 0, 0); imageData = ctx.getImageData(0, 0, canvas.width, canvas.height); }; img.src = "photo.jpg"; } window.applyGrayscale = () => { grayscale(imageData.data); ctx.putImageData(imageData, 0, 0); }; window.applyBrightness = () => { adjust_brightness(imageData.data, 1.3); ctx.putImageData(imageData, 0, 0); }; window.applyInvert = () => { invert(imageData.data); ctx.putImageData(imageData, 0, 0); }; setup(); </script> </body> </html>
Den centrale indsigt: imageData.data er et Uint8ClampedArray understottet af en ArrayBuffer. Nar det sendes til WASM, deler det den samme hukommelse - ingen kopiering. Rust-funktionen aendrer pixels direkte, og JavaScript-siden ser aendringerne ojeblikkeligt.
Lavere niveau: manuel WASM-instantiering
Hvis du ikke onsker at bruge wasm-bindgen, kan du instantiere WASM-moduler direkte:
const response = await fetch("calculator.wasm"); const { instance } = await WebAssembly.instantiateStreaming(response, { env: { // Functions the WASM module can call log_result: (value) => console.log("Result:", value), }, }); // Call exported functions const { add, multiply } = instance.exports; console.log(add(5, 3)); // 8 console.log(multiply(4, 7)); // 28
Dette er nyttigt, nar du onsker minimal overhead og ikke behover rig type-interop.
Ydeevne: WASM vs JavaScript
Virkelige benchmarks viser betydelige hastighedsforbedringer for CPU-intensive opgaver:
| Opgave | JavaScript | WASM | Hastighedsforhoejelse |
|---|---|---|---|
| 4K-billedbehandling | 180ms | 8ms (med SIMD) | 22x |
| Billedskalering (4K) | 250ms | 45ms | 5,5x |
| Fysiksimulering (10K entiteter) | Taber frames | Javaevnt 60fps | ~10x |
| JSON-parsing (stor payload) | 12ms | 3ms | 4x |
| Kryptografisk hashing | 45ms | 6ms | 7,5x |
WASM korer med cirka 95 % af nativ kodehastighed. De storste gevinster kommer fra:
- Forudsigelig ydeevne (ingen JIT-opvarmning, ingen GC-pauser)
- SIMD-instruktioner til parallel databehandling
- Direkte hukommelsesadgang uden garbage collector-interferens
Hvor WASM IKKE er hurtigere: DOM-manipulation, sma beregninger, I/O-bundne opgaver. JavaScript er allerede optimeret til disse.
Produktionsanvendelser
Figma: realtids-vektorrendering
Figmas kerne-rendering-motor er C++ kompileret til WASM. Enhver form, gradient og effekt beregnes i WASM og tegnes pa et Canvas-element. Dette gor det muligt for Figma at handtere komplekse designs med tusindvis af lag ved 60fps i browseren - ydeevne, der ville vaere umulig i rent JavaScript.
Adobe Photoshop pa nettet
Adobe porterede vigtige Photoshop-filtre og -vaerktojer til WASM med Rust. Deres benchmarks viser 4K-billedbehandling pa 22ms med WASM SIMD mod 180ms i JavaScript - en 8x forbedring, der gor realtids-filterforhandsvisninger mulige.
Cloudflare Workers
Cloudflare korer WASM-moduler i V8-isolates pa over 330 edge-lokationer. Cold starts er 1-5ms (sammenlignet med 100-500ms for containerbaseret serverless). I februar 2026 udrullede de Llama-3-8b-inferens over deres edge-netvaerk med WASM.
Google Meet
Baggrundssluering og virtuelle baggrunde i Google Meet bruger WASM med SIMD til realtids-videobehandling. WASM-modulet behandler hvert videoframe hurtigt nok til at opretholde javaevn video ved 30fps.
Browserunderstottelse (2026)
| Funktion | Chrome | Firefox | Safari | Edge |
|---|---|---|---|---|
| Core WASM | Fuld | Fuld | Fuld | Fuld |
| Threads | Ja | Ja | Ja | Ja |
| SIMD (128-bit) | Ja | Ja | Ja | Ja |
| WasmGC | 119+ | 120+ | 18.2+ | Ja |
| Exception Handling | Ja | Ja | Ja | Ja |
| Memory64 | Ja | Ja | Delvis | Ja |
Alle store browsere understotter WASM fuldt ud. De nyere funktioner (WasmGC, Exception Handling) har opnaet bred tilgaengelighed.
Tooling-reference
| Vaerktoej | Formal | Installation |
|---|---|---|
| wasm-pack | Byg Rust til WASM, generer npm-pakker | cargo install wasm-pack |
| wasm-bindgen | Rust/JS-interop-bindings (brugt af wasm-pack) | Dependency i Cargo.toml |
| wasm-opt | Optimering af binaerfilstorrelse (50%+ reduktion) | Del af Binaryen: brew install binaryen |
| wit-bindgen | Generer bindings fra WIT-filer | cargo install wit-bindgen-cli |
| Wasmtime | Server-side WASM-runtime (reference-WASI-implementering) | brew install wasmtime |
| Wasmer | Alternativ WASM-runtime med WASI-understottelse | curl https://get.wasmer.io -sSfL | sh |
| wasm-feature-detect | Runtime browser-funktionsdetektion | npm install wasm-feature-detect |
Optimering af binaerfilstorrelse
WASM-binaerfiler kan vaere store. Sadan formindsker du dem:
# Cargo.toml [profile.release] opt-level = "z" # Optimize for size lto = true # Link-time optimization codegen-units = 1 # Better optimization, slower compile strip = true # Strip debug symbols
# Build in release mode wasm-pack build --release --target web # Further optimize with wasm-opt wasm-opt -Oz pkg/image_processor_bg.wasm -o pkg/image_processor_bg.wasm
Et typisk Rust-WASM-modul gar fra 500KB til under 50KB med disse optimeringer.
Startroadmap
Konklusion
WebAssembly er ikke laengere eksperimentelt. Det er en produktionsteknologi, der bruges af nogle af de mest kraevende applikationer pa nettet. Naesten nativ ydeevne, sandboxet sikkerhed og universel portabilitet - intet andet kompileringsmal giver dig alle tre.
Du behover ikke omskrive hele din applikation i WASM. Start med en enkelt CPU-intensiv funktion - et billedfilter, en dataparser, en fysikberegning - kompiler den til WASM og kald den fra JavaScript. Mal forskellen. Beslu derefter, hvor WASM ellers kan hjaelpe.
Toolingen er moden, browserunderstottelsen er universel, og okosystemet vokser. Hvis du skriver Rust, er du allerede en kommando fra browseren.
Startcheckliste:
- Rust og wasm-pack installeret
- Forste WASM-modul bygget og korende i browseren
- JavaScript-interop virker (kald WASM fra JS)
- Release-build med storrelsesoptimeringer anvendt
- Ydeevne benchmarket mod rent JavaScript-akvivalent
- WASI udforsket med Wasmtime til server-side anvendelser