WebAssembly (WASM) nachinalsya kak sposob zapuska C++ v brauzere. V 2026 godu on rabotaet vezde - brauzery, servery, edge-seti, vstroennye ustroistva - i obespechivat rabotu nekotorykh iz samykh trebovatel'nykh prilozhenii v vebe. Dvizhok renderinga Figma, Adobe Photoshop v vebe, obrabotka video Google Meet i platforma edge-vychislenii Cloudflare - vse rabotaet na WebAssembly.
Chrome Platform Status pokazyvaet, chto WASM sostavliaet primerno 5,5% vsekh zagruzok stranits v Chrome na nachalo 2026 goda, po sravneniiu s 4,5% godom ranee. S tem chto WASM 3.0 stal standartom W3C, a WASI sozrevaet v napravlenii versii 1.0, ekosistema dostigla perelomnoho momenta.
Eto rukovodstvo okhvatyvaet vse, chto nuzhno znat' dlia nachala raboty s WebAssembly.
Chto takoe WebAssembly?
WebAssembly - eto binarnyi format instruktsii, razrabotannyi kak tsel' kompilyatsii. Vy pishete kod na yazyke vysokogo urovnya (Rust, C, C++, Go, Kotlin), kompiliruete ego v .wasm i zapuskaete v liuboi srede s WASM-runtime - brauzery, Node.js, Cloudflare Workers, Wasmtime ili Wasmer.
Kak eto rabotaet
WASM - eto stekovaya virtual'naya mashina. Funktsii pomeshchayut i izvlekayut znacheniya iz steka operandov. Runtime khosta (V8 v Chrome, SpiderMonkey v Firefox) JIT-kompiliruet baitkod WASM v nativnyi mashinnyi kod, poetomu proizvoditel'nost' blizka k nativnoi.
Klyuchevye kharakteristiki:
- Vypolnenie v peschanitse: WASM-moduli mogut poluchat' dostup tol'ko k resursam, kotorye khost yavno predostavlyaet. Net dostupa k failovoi sisteme, seti ili OS, esli eto ne razresheno. Eto fundamental'no otlichaetsya ot nativnogo koda.
- Lineinaya pamyat': odin nepreryivnyi
ArrayBuffer, razdelyaemyi mezhdu WASM i khostom. Slozhnye dannye (stroki, struktury) peredayutsya cherez zapis' v pamyat' i sovmestnoe ispol'zovanie ukazatelya. - Ogranichennye tipy: WASM nativno podderzhivaet tol'ko chetyre tipa:
i32,i64,f32,f64. Vse ostal'noe (stroki, massivy, ob'ekty) trebuet kodirovaniia cherez lineinuyu pamyat' ili Component Model. - Perenosimost': odin i tot zhe binarnyi fail
.wasmzapuskaetsya na liuboi platforme s WASM-runtime, bez perekompiliatsii.
WASM vs JavaScript
WASM ne zamenyaet JavaScript. On dopolnyaet ego.
| Aspekt | JavaScript | WebAssembly |
|---|---|---|
| Parsing | Parsing + kompilyatsiya v runtime | Predvaritel'no skompilirovannyi binarnyi fail, tol'ko dekodirovanie |
| Skorost' vypolneniia | JIT-optimizirovannaya, peremennaya | Blizko k nativnoi, stabil'naya |
| Zapusk | Bystryi dlya malenkikh skriptov | Bystroe dekodirovanie, predskazuemyi |
| Dostup k DOM | Pryamoi | Kosvennyi (cherez JS-prosloiku) |
| Luchshe vsego dlya | UI, manipulyatsiya DOM, obrabotka sobytii | CPU-intensivnye vychisleniya |
| Sborka musora | Vstroennaya | WasmGC (novoe) ili ruchnaya |
Ispol'zuiete JavaScript dlya raboty s UI i DOM. Ispol'zuiete WASM dlya tyazhelykh vychislenii: obrabotka izobrazhenii, kodirovanie video, fizicheskie simulyatsii, kriptografiya, parsing dannykh.
WASM 3.0: chto novogo
WebAssembly 3.0 stal standartom W3C v sentyabre 2025 goda, standartizovav devyat' funktsii, kotorye razrabatyvalis' godami.
| Funktsiya | Chto daet |
|---|---|
| WasmGC | Nativnaya sborka musora v WASM. Upravlyaemye yazyki (Java, Kotlin, Dart) mogut kompilirovat'sya v WASM bez dostavki svoego GC-runtime. Podderzhivaetsya v Chrome 119+, Firefox 120+, Safari 18.2+. |
| Exception Handling | Nativnyi try/catch v WASM. Ran'she isklyucheniya trebovali dorogikh krugovykh obkhodov k JavaScript. |
| Tail Calls | Obespechivayut effektivnuyu rekursiyu bez perepolneniya steka. Kritichno dlya funktsional'nykh yazykov. |
| Relaxed SIMD | 128-bitnye vektornye instruktsii dlya parallel'noi obrabotki dannykh. Pozvolyayut apparatnye optimizatsii. |
| Memory64 | Snimayut ogranichenie lineinoi pamyati v 4 GB. Neobkhodimo dlya masshtabnoi obrabotki dannykh. |
| Multi-memory | Neskol'ko nezavisimykh oblastei pamyati v odnom module. |
Samoe znachimoe - WasmGC. Ran'she kompilyatsiya Java ili Kotlin v WASM oznachala dostavku tselogo garbage collector-a kak chasti binarnogo faila, chto razduvalo razmery failov. Teper' sobstvennyi GC brauzera upravlyaet pamyat'yu WASM-modulei, tochno tak zhe, kak on delaet eto dlya JavaScript.
WASI: WebAssembly za predelami brauzera
WASM v brauzere moshchen, no WASI (WebAssembly System Interface) delaet WASM universal'nym runtime. WASI predostavlyaet standartizirovannye interfeisy dlya sistemnykh resursov - faily, set', chasy, sluchainye chisla - pozvolyaya WASM-modulyam rabotat' za predelami brauzera.
WASI Preview 2 (tekushchii stabil'nyi reliz) opredelyaet sleduyushchie interfeisy:
wasi:filesystem- failovye operatsii cherez capability handles (ne traditsionnye failovye deskriptory)wasi:sockets- set' TCP/UDPwasi:http- obrabotka HTTP-zaprosov/otvetovwasi:clocks- nastennye chasy, monotonnye chasywasi:random- kriptograficheskaya sluchainost'wasi:cli- argumenty komandnoi stroki, peremennye sredy, stdio
Klyuchevoi printsip - bezopasnost' na osnove vozmozhnostei: WASM-modul' ne mozhet poluchit' dostup k failovoi sisteme, esli khost yavno ne predostavit handle k konkretnoi direktorii. Eto delaet WASI fundamental'no bezopasnee zapuska nativnykh ispolnyaemykh failov.
Put' k WASI 1.0
WASI 0.3.0 (dobavlyayushchii async/primitivy parallelizma) ozhidaetsya v 2026 godu, WASI 1.0 dolzhen posledovat'. Glavnoe dopolnenie - integrirovannyi v yazyk async s potokovym I/O bez kopirovaniya.
Component Model
Bazovye WASM-moduli mogut obmenivat'sya tol'ko chislami. Component Model reshaet eto ogranichenie, dobavlyaya bogatuyu sistemu tipov i sloi kompozitsii poverh WASM.
WIT (WebAssembly Interface Types)
WIT - eto yazyk opredeleniya interfeisov, kotoryi pozvolyaet komponentam ob'yavlyat' svoi importy i eksporty s bogatymi tipami - stroki, zapisi, spiski, varianty, enumy - a ne tol'ko i32 i 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; }
Instrumenty, takie kak wit-bindgen, generiruyut yazykovye privyazki iz failov WIT. Komponent na Rust i komponent na Python mogut obmenivat'sya strokami, zapisyami i spiskami cherez kontrakty WIT, pri etom ni odna storona ne znaet yazyk realizatsii drugoi.
Sozdanie pervogo WASM-modulya na Rust
Rust obladaet naibolee zrelymi instrumentami dlya WASM. Sozdadim prakticheskii primer: modul' obrabotki izobrazhenii, rabotayushchii v brauzere.
Nastroika
# 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
Nastroika Cargo.toml
[package] name = "image-processor" version = "0.1.0" edition = "2021" [lib] crate-type = ["cdylib"] [dependencies] wasm-bindgen = "0.2"
Napishem kod na Rust
// 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 }
Sborka
wasm-pack build --target web
Eto sozdaet direktoriy pkg/ s:
image_processor_bg.wasm- skompilirovannyi WASM-binarnyi failimage_processor.js- JavaScript-konnektorskii kod s opredeleniyami TypeScriptpackage.json- gotov k publikatsii v npm
Ispol'zovanie v 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>
Klyuchevoi vyvod: imageData.data - eto Uint8ClampedArray, podderzhivaemyi ArrayBuffer. Pri peredache v WASM on razdelyaet tu zhe pamyat' - bez kopirovaniya. Funktsiya na Rust modifitsiruet pikseli na meste, i storona JavaScript vidaet izmeneniya nemedlenno.
Nizkorovnevyi uroven': ruchnaya initsializatsiya WASM
Esli vy ne khotite ispol'zovat' wasm-bindgen, vy mozhete sozdavat' ekzemplyary WASM-modulei napryamuyu:
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
Eto polezno, kogda vam nuzhny minimal'nye nakladnye raskhody i ne trebuetsya bogatyi tipovoi interop.
Proizvoditel'nost': WASM vs JavaScript
Real'nye benchmarki pokazyvayut znachitel'noe uskorenie dlya CPU-intensivnykh zadach:
| Zadacha | JavaScript | WASM | Uskorenie |
|---|---|---|---|
| Obrabotka izobrazheniya 4K | 180ms | 8ms (s SIMD) | 22x |
| Izmenenie razmera izobrazheniya (4K) | 250ms | 45ms | 5,5x |
| Fizicheskaya simulyatsiya (10K ob'ektov) | Propadayut kadry | Plavnye 60fps | ~10x |
| Parsing JSON (bol'shoi payload) | 12ms | 3ms | 4x |
| Kriptograficheskoe kheshirovanie | 45ms | 6ms | 7,5x |
WASM rabotaet na primerno 95% skorosti nativnogo koda. Naibol'shie vyigryshi dostigayutsya za schet:
- Predskazuemoi proizvoditel'nosti (net progreva JIT, net pauz GC)
- Instruktsii SIMD dlya parallel'noi obrabotki dannykh
- Pryamogo dostupa k pamyati bez vmeshatel'stva garbage collector-a
Gde WASM NE bystree: manipulyatsiya DOM, malye vychisleniya, zadachi s ogranichennym I/O. JavaScript uzhe optimizirovan dlya nikh.
Proizvodstvennye keisy
Figma: rendering vektorov v real'nom vremeni
Osnovnoi dvizhok renderinga Figma - eto C++, skompilirovannyi v WASM. Kazhdaya forma, gradient i effekt vychislyayutsya v WASM i risuutsya na element Canvas. Eto pozvolyaet Figma obrabatyvat' slozhnye dizainy s tysyachami sloev pri 60fps v brauzere - proizvoditel'nost', kotoraya byla by nevozmozhna na chistom JavaScript.
Adobe Photoshop v vebe
Adobe portirovala klyuchevye fil'try i instrumenty Photoshop v WASM s pomoshchyu Rust. Ikh benchmarki pokazyvayut obrabotku izobrazheniya 4K za 22ms s WASM SIMD protiv 180ms v JavaScript - 8-kratnoe uluchshenie, kotoroe delaet vozmozhnymi prevu fil'trov v real'nom vremeni.
Cloudflare Workers
Cloudflare zapuskaet WASM-moduli v izolyatakh V8 v bolee chem 330 edge-lokatsiyakh. Kholodnye starty sostavlyayut 1-5ms (po sravneniyu s 100-500ms dlya konteinernogo serverless). V fevrale 2026 goda oni razvernuli inferens Llama-3-8b po vsei svoei edge-seti s ispol'zovaniem WASM.
Google Meet
Razmytie fona i virtual'nye fony v Google Meet ispol'zuyut WASM s SIMD dlya obrabotki video v real'nom vremeni. WASM-modul' obrabatyvaet kazhdyi videokadr dostatochno bystro dlya podderzhaniya plavnogo video pri 30fps.
Podderzhka brauzerov (2026)
| Funktsiya | Chrome | Firefox | Safari | Edge |
|---|---|---|---|---|
| Core WASM | Polnaya | Polnaya | Polnaya | Polnaya |
| Threads | Da | Da | Da | Da |
| SIMD (128-bit) | Da | Da | Da | Da |
| WasmGC | 119+ | 120+ | 18.2+ | Da |
| Exception Handling | Da | Da | Da | Da |
| Memory64 | Da | Da | Chastichno | Da |
Vse osnovnye brauzery polnost'yu podderzhivayut WASM. Bolee novye funktsii (WasmGC, Exception Handling) dostigli shirokoi dostupnosti.
Spravochnik po instrumentam
| Instrument | Naznachenie | Ustanovka |
|---|---|---|
| wasm-pack | Sborka Rust v WASM, generatsiya npm-paketov | cargo install wasm-pack |
| wasm-bindgen | Privyazki Rust/JS interop (ispol'zuetsya wasm-pack) | Zavisimost' v Cargo.toml |
| wasm-opt | Optimizatsiya razmera binarnogo faila (50%+ umen'shenie) | Chast' Binaryen: brew install binaryen |
| wit-bindgen | Generatsiya privyazok iz WIT-failov | cargo install wit-bindgen-cli |
| Wasmtime | Servernyi WASM-runtime (etalonnaya realizatsiya WASI) | brew install wasmtime |
| Wasmer | Al'ternativnyi WASM-runtime s podderzhkoi WASI | curl https://get.wasmer.io -sSfL | sh |
| wasm-feature-detect | Obnaruzhenie funktsii brauzera vo vremya vypolneniya | npm install wasm-feature-detect |
Optimizatsiya razmera binarnogo faila
WASM-binarniki mogut byt' bol'shimi. Vot kak ikh umen'shit':
# 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
Tipichnyi WASM-modul' na Rust umen'shaetsya s 500KB do menee 50KB s etimi optimizatsiyami.
Plan deistvii dlya starta
Zaklyuchenie
WebAssembly bol'she ne yavlyaetsya eksperimental'noi tekhnologiei. Eto proizvodstvennaya tekhnologiya, ispol'zuemaya nekotorymi iz samykh trebovatel'nykh prilozhenii v vebe. Proizvoditel'nost' blizko k nativnoi, bezopasnost' peschanitsy i universal'naya perenosimost' - ni odna drugaya tsel' kompilyatsii ne daet vsekh trekh odnovremenno.
Vam ne nuzhno perepisyvat' vse prilozhenie na WASM. Nachnite s odnoi CPU-intensivnoi funktsii - fil'tra izobrazheniya, parsera dannykh, fizicheskogo rascheta - skompilyiruiete ee v WASM i vyzoviete iz JavaScript. Izmer'te raznitsu. Zatem reshite, gde eshche WASM mozhet pomoch'.
Instrumenty zrely, podderzhka brauzerov universal'na, i ekosistema rastet. Esli vy pishete na Rust, vy uzhe v odnoi komande ot brauzera.
Kontrol'nyi spisok dlya starta:
- Rust i wasm-pack ustanovleny
- Pervyi WASM-modul' sobran i zapushchen v brauzere
- JavaScript interop rabotaet (vyzov WASM iz JS)
- Reliznaya sborka s optimizatsiyami razmera primenena
- Proizvoditel'nost' sravnena s ekvivalentom na chistom JavaScript
- WASI issledovan s Wasmtime dlya severnykh keisov