spinny:~/writing $ less webassembly-wasm-complete-guide.md
12WebAssembly (WASM) zaczal jako sposob na uruchamianie C++ w przegladarce. W 2026 roku dziala wszedzie - przegladarki, serwery, sieci edge, urzadzenia wbudowane - i napedza jedne z najbardziej wymagajacych aplikacji w sieci. Silnik renderujacy Figmy, Adobe Photoshop w wersji webowej, przetwarzanie wideo Google Meet i platforma obliczen edge Cloudflare - wszystko dziala na WebAssembly.34Chrome Platform Status podaje, ze WASM stanowi okolo 5,5% wszystkich zaladowan stron w Chrome na poczatku 2026 roku, w porownaniu z 4,5% rok wczesniej. Wraz z tym, ze WASM 3.0 zostal standardem W3C, a WASI dojrzewa w kierunku wersji 1.0, ekosystem osiagnal punkt zwrotny.56Ten przewodnik obejmuje wszystko, co musisz wiedziec, zeby zaczac budowac z WebAssembly.78## Czym jest WebAssembly?910WebAssembly to binarny format instrukcji zaprojektowany jako cel kompilacji. Piszesz kod w jezyku wysokiego poziomu (Rust, C, C++, Go, Kotlin), kompilujesz go do `.wasm` i uruchamiasz w dowolnym srodowisku posiadajacym runtime WASM - przegladarki, Node.js, Cloudflare Workers, Wasmtime lub Wasmer.1112```mermaid13graph LR14 Rust[Rust / C / C++] --> Compiler[Compiler]15 Compiler --> WASM[.wasm Binary]16 WASM --> Browser[Browser V8/SpiderMonkey]17 WASM --> Server[Server Wasmtime]18 WASM --> Edge[Edge Cloudflare Workers]19 WASM --> Embedded[Embedded WAMR]20```2122### Jak to dziala2324WASM to **maszyna wirtualna oparta na stosie**. Funkcje umieszczaja i pobieraja wartosci ze stosu operandow. Runtime hosta (V8 w Chrome, SpiderMonkey w Firefoksie) kompiluje JIT bajtkod WASM do natywnego kodu maszynowego, dlatego wydajnosc jest bliska natywnej.2526Kluczowe cechy:2728- **Wykonanie w piaskownicy**: moduly WASM moga uzyskac dostep tylko do zasobow, ktore host jawnie przyznaje. Brak dostepu do systemu plikow, sieci ani systemu operacyjnego, chyba ze zostanie to dozwolone. To fundamentalna roznica w porownaniu z kodem natywnym.29- **Pamiec liniowa**: pojedynczy ciagly `ArrayBuffer` wspoldzielony miedzy WASM a hostem. Zlezone dane (stringi, struktury) sa przekazywane przez zapis do pamieci i udostepnienie wskaznika.30- **Ograniczone typy**: WASM natywnie obsluguje tylko cztery typy: `i32`, `i64`, `f32`, `f64`. Wszystko inne (stringi, tablice, obiekty) wymaga kodowania przez pamiec liniowa lub Component Model.31- **Przenosnosc**: ten sam plik binarny `.wasm` dziala na dowolnej platformie z runtime WASM, bez rekompilacji.3233### WASM vs JavaScript3435WASM nie zastepuje JavaScriptu. Uzupelnia go.3637| Aspekt | JavaScript | WebAssembly |38|--------|-----------|-------------|39| **Parsowanie** | Parsowanie + kompilacja w runtime | Wstepnie skompilowany plik binarny, tylko dekodowanie |40| **Szybkosc wykonania** | Zoptymalizowany JIT, zmienny | Blisko natywny, stalej jakosci |41| **Start** | Szybki dla malych skryptow | Szybkie dekodowanie, przewidywalny |42| **Dostep do DOM** | Bezposredni | Posredni (przez warstwe JS) |43| **Najlepszy do** | UI, manipulacja DOM, obsluga zdarzen | Intensywne obliczenia CPU |44| **Odsmiecanie pamieci** | Wbudowane | WasmGC (nowe) lub reczne |4546Uzywaj JavaScriptu do pracy z UI i DOM. Uzywaj WASM do ciezkich obliczen: przetwarzanie obrazow, kodowanie wideo, symulacje fizyczne, kryptografia, parsowanie danych.4748## WASM 3.0: co nowego4950WebAssembly 3.0 zostal standardem W3C we wrzesniu 2025 roku, standaryzujac dziewiec funkcji, ktore byly rozwijane przez lata.5152| Funkcja | Co umozliwia |53|---------|----------------|54| **WasmGC** | Natywne odsmiecanie pamieci w WASM. Jezyki zarzadzane (Java, Kotlin, Dart) moga kompilowac do WASM bez dolaczania wlasnego runtime GC. Obslugiwane w Chrome 119+, Firefox 120+, Safari 18.2+. |55| **Exception Handling** | Natywne `try`/`catch` w WASM. Wczesniej wyjatki wymagaly kosztownych przejsc do JavaScriptu. |56| **Tail Calls** | Umozliwia efektywna rekurencje bez przepelnienia stosu. Kluczowe dla jezykow funkcyjnych. |57| **Relaxed SIMD** | 128-bitowe instrukcje wektorowe do rownoleglego przetwarzania danych. Umozliwia optymalizacje specyficzne dla sprzetu. |58| **Memory64** | Przełamuje limit 4GB pamieci liniowej. Wymagane do przetwarzania danych na duza skale. |59| **Multi-memory** | Wiele niezaleznych regionow pamieci w jednym module. |6061Najbardziej przelomowy jest **WasmGC**. Wczesniej kompilacja Javy lub Kotlina do WASM oznaczala dolaczenie calego garbage collectora jako czesci pliku binarnego, co znacznie zwiększalo rozmiar plikow. Teraz wlasny GC przegladarki zarzadza pamiecia modulow WASM, tak jak robi to dla JavaScriptu.6263## WASI: WebAssembly poza przegladarka6465WASM w przegladarce jest potezny, ale **WASI (WebAssembly System Interface)** sprawia, ze WASM staje sie uniwersalnym runtime. WASI zapewnia znormalizowane interfejsy do zasobow systemowych - pliki, siec, zegary, liczby losowe - umozliwiajac uruchamianie modulow WASM poza przegladarka.6667```mermaid68graph TD69 subgraph "Browser"70 B[WASM Module] --> Web[Web APIs\nDOM, Fetch, Canvas]71 end7273 subgraph "Server / Edge / Embedded"74 S[WASM Module] --> WASI[WASI Interfaces]75 WASI --> FS[wasi:filesystem]76 WASI --> Net[wasi:sockets]77 WASI --> HTTP[wasi:http]78 WASI --> Clock[wasi:clocks]79 WASI --> Rand[wasi:random]80 end81```8283WASI Preview 2 (obecne stabilne wydanie) definiuje nastepujace interfejsy:8485- `wasi:filesystem` - operacje na plikach za pomoca uchwytow uprawnien (nie tradycyjnych deskryptorow plikow)86- `wasi:sockets` - siec TCP/UDP87- `wasi:http` - obsluga zadan/odpowiedzi HTTP88- `wasi:clocks` - zegar scienny, zegar monotoniczny89- `wasi:random` - kryptograficzna losowosc90- `wasi:cli` - argumenty wiersza polecen, zmienne srodowiskowe, stdio9192Kluczowa zasada to **bezpieczenstwo oparte na uprawnieniach**: modul WASM nie moze uzyskac dostepu do systemu plikow, chyba ze host jawnie przyznaje uchwyt do okreslonego katalogu. To sprawia, ze WASI jest fundamentalnie bezpieczniejszy niz uruchamianie natywnych plikow wykonywalnych.9394### Droga do WASI 1.09596WASI 0.3.0 (dodajacy prymitywy async/wspolbieznosci) jest oczekiwany w 2026 roku, a WASI 1.0 ma nastapic potem. Glownym dodatkiem jest zintegrowane z jezykiem async z bezkopiowym strumieniowym I/O.9798## Component Model99100Podstawowe moduly WASM moga wymieniac tylko liczby. **Component Model** rozwiazuje to ograniczenie, dodajac bogaty system typow i warstwe kompozycji na szczycie WASM.101102### WIT (WebAssembly Interface Types)103104WIT to jezyk definicji interfejsow, ktory pozwala komponentom deklarowac importy i eksporty z bogatymi typami - stringi, rekordy, listy, warianty, enumy - nie tylko `i32` i `f64`.105106```wit107// calculator.wit108package myorg:calculator@1.0.0;109110interface operations {111 record calculation {112 expression: string,113 result: f64,114 timestamp: u64,115 }116117 add: func(a: f64, b: f64) -> f64;118 multiply: func(a: f64, b: f64) -> f64;119 history: func() -> list<calculation>;120}121122world calculator {123 export operations;124}125```126127Lancuchy narzedzi takie jak `wit-bindgen` generuja powiazania specyficzne dla jezyka z plikow WIT. Komponent w Rust i komponent w Pythonie moga wymieniac stringi, rekordy i listy poprzez kontrakty WIT, bez koniecznosci znajomosci jezyka implementacji drugiej strony.128129## Budowanie pierwszego modulu WASM z Rust130131Rust ma najbardziej dojrzale narzedzia WASM. Zbudujmy praktyczny przyklad: modul przetwarzania obrazow dzialajacy w przegladarce.132133### Konfiguracja134135```bash136# Install the WASM target for Rust137rustup target add wasm32-unknown-unknown138139# Install wasm-pack (builds Rust to WASM + generates JS bindings)140cargo install wasm-pack141142# Create a new library project143cargo new --lib image-processor144cd image-processor145```146147### Konfiguracja Cargo.toml148149```toml150[package]151name = "image-processor"152version = "0.1.0"153edition = "2021"154155[lib]156crate-type = ["cdylib"]157158[dependencies]159wasm-bindgen = "0.2"160```161162### Napisz kod Rust163164```rust165// src/lib.rs166use wasm_bindgen::prelude::*;167168/// Convert an image buffer to grayscale.169/// Input: RGBA pixel data as a flat u8 array (4 bytes per pixel).170/// Output: Modified in place for zero-copy performance.171#[wasm_bindgen]172pub fn grayscale(pixels: &mut [u8]) {173 for chunk in pixels.chunks_exact_mut(4) {174 let r = chunk[0] as f32;175 let g = chunk[1] as f32;176 let b = chunk[2] as f32;177 // ITU-R BT.709 luminance coefficients178 let gray = (0.2126 * r + 0.7152 * g + 0.0722 * b) as u8;179 chunk[0] = gray;180 chunk[1] = gray;181 chunk[2] = gray;182 // chunk[3] is alpha, leave unchanged183 }184}185186/// Adjust brightness of an image.187/// factor > 1.0 brightens, < 1.0 darkens.188#[wasm_bindgen]189pub fn adjust_brightness(pixels: &mut [u8], factor: f32) {190 for chunk in pixels.chunks_exact_mut(4) {191 chunk[0] = ((chunk[0] as f32 * factor).min(255.0)) as u8;192 chunk[1] = ((chunk[1] as f32 * factor).min(255.0)) as u8;193 chunk[2] = ((chunk[2] as f32 * factor).min(255.0)) as u8;194 }195}196197/// Invert all colors in the image.198#[wasm_bindgen]199pub fn invert(pixels: &mut [u8]) {200 for chunk in pixels.chunks_exact_mut(4) {201 chunk[0] = 255 - chunk[0];202 chunk[1] = 255 - chunk[1];203 chunk[2] = 255 - chunk[2];204 }205}206207/// Calculate the average brightness of an image (0-255).208#[wasm_bindgen]209pub fn average_brightness(pixels: &[u8]) -> f32 {210 let mut total: f64 = 0.0;211 let pixel_count = pixels.len() / 4;212 for chunk in pixels.chunks_exact(4) {213 let luminance = 0.2126 * chunk[0] as f64214 + 0.7152 * chunk[1] as f64215 + 0.0722 * chunk[2] as f64;216 total += luminance;217 }218 (total / pixel_count as f64) as f32219}220```221222### Budowanie223224```bash225wasm-pack build --target web226```227228To tworzy katalog `pkg/` zawierajacy:229- `image_processor_bg.wasm` - skompilowany plik binarny WASM230- `image_processor.js` - kod laczacy JavaScript z definicjami TypeScript231- `package.json` - gotowy do publikacji w npm232233### Uzycie w JavaScript234235```html236<!DOCTYPE html>237<html>238<head><title>WASM Image Processor</title></head>239<body>240 <canvas id="canvas" width="800" height="600"></canvas>241 <button onclick="applyGrayscale()">Grayscale</button>242 <button onclick="applyBrightness()">Brighten</button>243 <button onclick="applyInvert()">Invert</button>244245 <script type="module">246 import init, { grayscale, adjust_brightness, invert } from "./pkg/image_processor.js";247248 let ctx;249 let imageData;250251 async function setup() {252 await init();253 const canvas = document.getElementById("canvas");254 ctx = canvas.getContext("2d");255256 // Load an image onto the canvas257 const img = new Image();258 img.onload = () => {259 ctx.drawImage(img, 0, 0);260 imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);261 };262 img.src = "photo.jpg";263 }264265 window.applyGrayscale = () => {266 grayscale(imageData.data);267 ctx.putImageData(imageData, 0, 0);268 };269270 window.applyBrightness = () => {271 adjust_brightness(imageData.data, 1.3);272 ctx.putImageData(imageData, 0, 0);273 };274275 window.applyInvert = () => {276 invert(imageData.data);277 ctx.putImageData(imageData, 0, 0);278 };279280 setup();281 </script>282</body>283</html>284```285286Kluczowy wniosek: `imageData.data` to `Uint8ClampedArray` oparty na `ArrayBuffer`. Przy przekazywaniu do WASM wspoldziela te sama pamiec - bez kopiowania. Funkcja Rust modyfikuje piksele w miejscu, a strona JavaScript natychmiast widzi zmiany.287288## Nizszy poziom: reczna instancjacja WASM289290Jesli nie chcesz uzywac `wasm-bindgen`, mozesz bezposrednio tworzyc instancje modulow WASM:291292```javascript293const response = await fetch("calculator.wasm");294const { instance } = await WebAssembly.instantiateStreaming(response, {295 env: {296 // Functions the WASM module can call297 log_result: (value) => console.log("Result:", value),298 },299});300301// Call exported functions302const { add, multiply } = instance.exports;303console.log(add(5, 3)); // 8304console.log(multiply(4, 7)); // 28305```306307Jest to przydatne, gdy chcesz minimalnego narzutu i nie potrzebujesz bogatego interop typow.308309## Wydajnosc: WASM vs JavaScript310311Rzeczywiste benchmarki pokazuja znaczne przyspieszenia dla zadan intensywnie obciazajacych CPU:312313| Zadanie | JavaScript | WASM | Przyspieszenie |314|------|-----------|------|---------|315| Przetwarzanie obrazu 4K | 180ms | 8ms (z SIMD) | 22x |316| Zmiana rozmiaru obrazu (4K) | 250ms | 45ms | 5,5x |317| Symulacja fizyczna (10K obiektow) | Utrata klatek | Plynne 60fps | ~10x |318| Parsowanie JSON (duzy payload) | 12ms | 3ms | 4x |319| Hashowanie kryptograficzne | 45ms | 6ms | 7,5x |320321WASM dziala z okolo 95% predkosci kodu natywnego. Najwieksze zyski wynikaja z:322- Przewidywalnej wydajnosci (brak rozgrzewki JIT, brak pauz GC)323- Instrukcji SIMD do rownoleglego przetwarzania danych324- Bezposredniego dostepu do pamieci bez ingerencji garbage collectora325326Gdzie WASM NIE jest szybszy: manipulacja DOM, male obliczenia, zadania ograniczone przez I/O. JavaScript jest juz do tego zoptymalizowany.327328## Przypadki uzycia produkcyjnego329330### Figma: renderowanie wektorow w czasie rzeczywistym331332Glowny silnik renderujacy Figmy to C++ skompilowany do WASM. Kazdy ksztalt, gradient i efekt jest obliczany w WASM i rysowany na elemencie Canvas. Pozwala to Figmie obslugiwac zlozone projekty z tysiacami warstw przy 60fps w przegladarce - wydajnosc, ktora bylaby niemozliwa w czystym JavaScripcie.333334### Adobe Photoshop w przegladarce335336Adobe przenioslo kluczowe filtry i narzedzia Photoshopa do WASM przy uzyciu Rust. Ich benchmarki pokazuja przetwarzanie obrazu 4K w 22ms z WASM SIMD vs 180ms w JavaScripcie - 8-krotna poprawa, ktora umozliwia podglad filtrow w czasie rzeczywistym.337338### Cloudflare Workers339340Cloudflare uruchamia moduly WASM w izolatach V8 w ponad 330 lokalizacjach edge. Zimne starty trwaja 1-5ms (w porownaniu ze 100-500ms dla serverless opartego na kontenerach). W lutym 2026 roku wdrozyli wnioskowanie Llama-3-8b w calej sieci edge przy uzyciu WASM.341342### Google Meet343344Rozmycie tla i wirtualne tla w Google Meet uzywaja WASM z SIMD do przetwarzania wideo w czasie rzeczywistym. Modul WASM przetwarza kazda klatke wideo wystarczajaco szybko, aby utrzymac plynne wideo przy 30fps.345346## Obsluga przegladarek (2026)347348| Funkcja | Chrome | Firefox | Safari | Edge |349|---------|--------|---------|--------|------|350| Core WASM | Pelna | Pelna | Pelna | Pelna |351| Threads | Tak | Tak | Tak | Tak |352| SIMD (128-bit) | Tak | Tak | Tak | Tak |353| WasmGC | 119+ | 120+ | 18.2+ | Tak |354| Exception Handling | Tak | Tak | Tak | Tak |355| Memory64 | Tak | Tak | Czesciowo | Tak |356357Wszystkie glowne przegladarki w pelni obsluguja WASM. Nowsze funkcje (WasmGC, Exception Handling) osiagnely szeroka dostepnosc.358359## Referencje narzedzi360361| Narzedzie | Przeznaczenie | Instalacja |362|------|---------|---------|363| **wasm-pack** | Budowanie Rust do WASM, generowanie pakietow npm | `cargo install wasm-pack` |364| **wasm-bindgen** | Powiazania interop Rust/JS (uzywane przez wasm-pack) | Zaleznosc w Cargo.toml |365| **wasm-opt** | Optymalizacja rozmiaru pliku binarnego (50%+ redukcji) | Czesc Binaryen: `brew install binaryen` |366| **wit-bindgen** | Generowanie powiazan z plikow WIT | `cargo install wit-bindgen-cli` |367| **Wasmtime** | Serwerowy runtime WASM (referencyjna implementacja WASI) | `brew install wasmtime` |368| **Wasmer** | Alternatywny runtime WASM z obsluga WASI | `curl https://get.wasmer.io -sSfL \| sh` |369| **wasm-feature-detect** | Wykrywanie funkcji przegladarki w runtime | `npm install wasm-feature-detect` |370371### Optymalizacja rozmiaru pliku binarnego372373Pliki binarne WASM moga byc duze. Oto jak je zmniejszyc:374375```toml376# Cargo.toml377[profile.release]378opt-level = "z" # Optimize for size379lto = true # Link-time optimization380codegen-units = 1 # Better optimization, slower compile381strip = true # Strip debug symbols382```383384```bash385# Build in release mode386wasm-pack build --release --target web387388# Further optimize with wasm-opt389wasm-opt -Oz pkg/image_processor_bg.wasm -o pkg/image_processor_bg.wasm390```391392Typowy modul Rust WASM zmniejsza sie z 500KB do ponizej 50KB przy tych optymalizacjach.393394## Plan dzialania na start395396```mermaid397flowchart TD398 A[Week 1: Basics] --> B[Week 2: Real Project]399 B --> C[Week 3: WASI and Server-side]400 C --> D[Month 2+: Production]401402 A --> A1[Install Rust + wasm-pack]403 A --> A2[Build hello-world WASM module]404 A --> A3[Call WASM functions from JavaScript]405406 B --> B1[Build image processor or game physics]407 B --> B2[Use wasm-bindgen for rich types]408 B --> B3[Benchmark against pure JS]409410 C --> C1[Run WASM with Wasmtime]411 C --> C2[Explore WASI interfaces]412 C --> C3[Try Component Model with WIT]413414 D --> D1[Optimize binary size]415 D --> D2[Use SIMD for parallelism]416 D --> D3[Deploy to Cloudflare Workers or browser]417```418419## Podsumowanie420421WebAssembly nie jest juz technologia eksperymentalna. To technologia produkcyjna uzywana przez jedne z najbardziej wymagajacych aplikacji w sieci. Wydajnosc bliska natywnej, bezpieczenstwo piaskownicy i uniwersalna przenosnosc - zaden inny cel kompilacji nie daje wszystkich trzech jednoczesnie.422423Nie musisz przepisywac calej aplikacji w WASM. Zacznij od pojedynczej funkcji intensywnie obciazajacej CPU - filtra obrazu, parsera danych, obliczen fizycznych - skompiluj ja do WASM i wywolaj z JavaScriptu. Zmierz roznice. Potem zdecyduj, gdzie jeszcze WASM moze pomoc.424425Narzedzia sa dojrzale, obsluga przegladarek jest uniwersalna, a ekosystem rosnie. Jesli piszesz w Rust, jestes juz o jedno polecenie od przegladarki.426427> **Lista kontrolna na start:**428>429> - [x] Rust i wasm-pack zainstalowane430> - [x] Pierwszy modul WASM zbudowany i uruchomiony w przegladarce431> - [x] Interop z JavaScript dziala (wywoływanie WASM z JS)432> - [x] Wersja release z optymalizacjami rozmiaru zastosowana433> - [x] Wydajnosc porownana z odpowiednikiem w czystym JavaScripcie434> - [x] WASI zbadane z Wasmtime dla przypadkow uzycia po stronie serwera435
:WebAssembly dla programistow webowych: od zera do produkcjilines 1-435 (END) — press q to close