Czym jest WebAssembly
WebAssembly (w skrócie WASM) to format binarny zaprojektowany do uruchamiania w przeglądarce internetowej z wydajnością zbliżoną do kodu natywnego. To nie jest język programowania — to cel kompilacji. Piszesz kod w C, C++, Rust, Go lub innym wspieranym języku, a kompilator generuje moduł WASM, który przeglądarka potrafi wykonać.
Tradycyjnie jedynym językiem wykonywanym w przeglądarce był JavaScript. WASM nie zastępuje JavaScriptu — uzupełnia go. JavaScript jest doskonały do manipulacji DOM, obsługi zdarzeń i logiki interfejsu. WASM przejmuje zadania wymagające intensywnych obliczeń, gdzie JavaScript jest zbyt wolny.
Standard WebAssembly jest rozwijany przez W3C i wspierany przez wszystkie główne przeglądarki od 2017 roku — Chrome, Firefox, Safari i Edge. To nie eksperymentalna technologia, lecz dojrzały standard z szerokim wsparciem.
Jak to działa
Moduł WASM to plik binarny z rozszerzeniem .wasm, który przeglądarka pobiera, kompiluje do kodu maszynowego i wykonuje w izolowanym środowisku (sandbox). Proces wygląda tak:
- Kompilator (np. Rust → wasm-pack, Go →
GOOS=js GOARCH=wasm go build) generuje plik.wasm - JavaScript na stronie ładuje moduł:
WebAssembly.instantiateStreaming(fetch('app.wasm')) - Przeglądarka kompiluje WASM do natywnego kodu maszynowego (ahead-of-time lub just-in-time)
- Kod JavaScript wywołuje eksportowane funkcje z modułu WASM i odbiera wyniki
WASM działa w tym samym sandboxie co JavaScript — nie ma bezpośredniego dostępu do DOM, systemu plików ani sieci. Komunikacja z otoczeniem odbywa się wyłącznie przez API udostępnione przez hosta (przeglądarkę). To gwarantuje bezpieczeństwo — moduł WASM nie może zrobić niczego, czego nie mógłby zrobić JavaScript.
Kiedy WebAssembly ma sens
WASM nie jest uniwersalnym rozwiązaniem. Dodaje złożoność — trzeba skonfigurować toolchain kompilacji, zarządzać komunikacją między JS a WASM i debugować kod na dwóch poziomach. Opłaca się w konkretnych scenariuszach.
Przetwarzanie obrazów i wideo — aplikacje takie jak Figma, Photoshop Web czy edytory wideo korzystają z WASM do manipulacji pikselami, filtrów, transformacji i kodowania. Operacje na milionach pikseli w JavaScript byłyby zbyt wolne.
Gry przeglądarkowe — silniki gier (Unity, Unreal Engine) mogą kompilować się do WASM, uruchamiając złożone gry 3D bezpośrednio w przeglądarce. Doom 3, Quake i wiele gier indie działa w WASM z płynną animacją.
Kryptografia i kompresja — operacje kryptograficzne, hashowanie, kompresja/dekompresja danych to zadania idealnie pasujące do WASM. Biblioteki takie jak libsodium czy zlib mają porty WASM.
Narzędzia deweloperskie w przeglądarce — edytory kodu (np. VS Code for Web), kompilatory, lintery i formatery mogą działać lokalnie w przeglądarce dzięki WASM, bez wysyłania kodu na serwer.
Emulacja i kompatybilność — uruchamianie istniejącego kodu C/C++ w przeglądarce bez przepisywania. SQLite skompilowany do WASM działa jako baza danych w przeglądarce. FFmpeg w WASM konwertuje formaty wideo po stronie klienta.
Kompilacja Go do WebAssembly
Go wspiera kompilację do WASM od wersji 1.11. Proces jest prosty:
GOOS=js GOARCH=wasm go build -o app.wasm main.go
Go generuje moduł WASM plus wymaga pliku wasm_exec.js (dostarczanego z instalacją Go), który zapewnia środowisko uruchomieniowe. Strona HTML ładuje oba pliki i uruchamia moduł.
Zalety Go+WASM:
- Istniejący kod Go można skompilować do WASM z minimalnymi zmianami
- Pełna biblioteka standardowa jest dostępna (z pewnymi ograniczeniami)
- Goroutines działają w WASM
Wady:
- Rozmiar modułu — nawet prosty program Go generuje WASM o rozmiarze 5-15 MB, ponieważ zawiera cały runtime Go z garbage collectorem. To znacznie więcej niż moduły z C czy Rust.
- Wydajność — Go+WASM jest wolniejsze niż Rust+WASM ze względu na overhead garbage collectora
Alternatywa: TinyGo — kompilator Go zoptymalizowany pod kątem małych celów, generujący moduły WASM rzędu 100 KB-1 MB kosztem ograniczonej biblioteki standardowej.
Kompilacja Rust do WebAssembly
Rust jest uważany za najlepszy język do tworzenia modułów WASM. Powody:
- Minimalny rozmiar — brak garbage collectora i minimalny runtime. Prosty moduł Rust+WASM waży kilka-kilkadziesiąt KB.
- Maksymalna wydajność — Rust generuje kod zbliżony wydajnością do ręcznie napisanego C
- Doskonały toolchain —
wasm-packautomatyzuje kompilację, generowanie bindingów JS i publikację do npm - wasm-bindgen — biblioteka automatyzująca komunikację między Rust a JavaScript
Ekosystem Rust+WASM jest najbardziej dojrzały. Projekty takie jak yew (framework frontendowy w Rust) czy leptos pozwalają budować całe aplikacje webowe w Rust, kompilowane do WASM.
Wydajność — liczby
Jak duża jest różnica w wydajności między WASM a JavaScript? Zależy od zadania:
- Obliczenia numeryczne (sortowanie, operacje macierzowe, symulacje) — WASM jest 2-10x szybszy niż JavaScript
- Przetwarzanie tekstu — różnica jest mniejsza, 1,5-3x, bo silniki JS (V8, SpiderMonkey) są świetnie zoptymalizowane pod operacje na stringach
- Manipulacja DOM — WASM jest wolniejszy, bo musi przechodzić przez barierę JS-WASM przy każdym wywołaniu DOM API
Kluczowa zasada: WASM opłaca się, gdy masz dużo obliczeń do wykonania wewnątrz modułu i mało komunikacji z DOM. Jeśli Twój kod to głównie manipulacja DOM z drobnymi obliczeniami — JavaScript będzie szybszy.
WASM poza przeglądarką
WebAssembly wykracza poza przeglądarkę. WASI (WebAssembly System Interface) to standard pozwalający uruchamiać moduły WASM jako samodzielne programy na serwerze, z kontrolowanym dostępem do systemu plików, sieci i zmiennych środowiskowych.
Runtime'y takie jak Wasmtime, Wasmer i WasmEdge uruchamiają moduły WASM na serwerze z bezpieczeństwem sandboxa i wydajnością zbliżoną do natywnej. To otwiera drogę do nowego modelu deploymentu — "kompiluj raz, uruchom wszędzie" z izolacją na poziomie modułu.
Docker i Kubernetes eksperymentują z obsługą kontenerów WASM. Solomon Hykes (twórca Dockera) powiedział: "Gdyby WASM+WASI istniał w 2008 roku, nie musielibyśmy tworzyć Dockera".
Podsumowanie
WebAssembly to potężne narzędzie, które rozszerza możliwości przeglądarki o wydajne obliczenia, dotąd zarezerwowane dla aplikacji natywnych. Nie zastępuje JavaScriptu — uzupełnia go tam, gdzie JS jest zbyt wolny. Najlepsze wyniki daje w przetwarzaniu danych, grach, kryptografii i uruchamianiu istniejącego kodu C/C++/Rust w przeglądarce.
Dla większości stron firmowych i aplikacji CRUD WebAssembly nie jest potrzebny. Ale jeśli Twój projekt wymaga intensywnych obliczeń po stronie klienta, warto go rozważyć. Skontaktuj się z nami — pomożemy ocenić, czy WASM pasuje do Twojego przypadku użycia.