WebAssembly — это бинарный формат инструкций, который позволяет запускать код, написанный на C/C++, Rust, Go, C# и других языках, прямо в браузере со скоростью, близкой к нативной. При этом WASM работает в песочнице, как и JavaScript, но загружается и выполняется в 10–20 раз быстрее интерпретируемого JS.
Зачем нужен WASM, если есть JavaScript?
Как это работает
Минимальный пример: считаем факториал
C++:
Компиляция:
HTML:
Граница JS ↔ WASM: память и FFI
Реальные кейсы
Сколько весит runtime
Ограничения
Будущее
Итого
WASM — это не замена JavaScript, а его «задняя передача» для тяжёлых вычислений. Если вашей задачи хватает JS — оставайтесь на нём. Если нужен Photoshop-уровень производительности — компилируйте в WASM и наслаждайтесь почти родной скоростью в любой вкладке.
Полезные ресурсы
Зачем нужен WASM, если есть JavaScript?
- Высокие вычисления: фото- и видеофильтры, 3D-рендеринг, CAD, игры.
- Портирование существующих библиотек: нет нужды переписывать миллионы строк C++ на JS.
- Предсказуемая производительность: строгая типизация + компиляция AOT.
- Кроссплатформенность: один бинарник работает на Windows, macOS, Linux, Android, iOS.
Как это работает
- Пишем код на C++ (или Rust).
- Компилируем в
.wasmс помощью Emscripten (для C/C++) или wasm-pack (для Rust). - Получаем два файла:
module.wasmи JS-обвязку для загрузки. - Используем WebAssembly API в браузере:
Код:const { instance } = await WebAssembly.instantiateStreaming(fetch('module.wasm')); console.log(instance.exports.add(1, 2)); // 3
Минимальный пример: считаем факториал
C++:
Код:
extern "C" int fact(int n) {
return n <= 1 ? 1 : n * fact(n - 1);
}
Компиляция:
Код:
emcc fact.cpp -O3 -s MODULARIZE=1 -s EXPORTED_FUNCTIONS='["_fact"]' -o fact.js
HTML:
Код:
<script type="module">
import init, { fact } from './fact.js';
await init();
console.log('5! =', fact(5)); // 120
</script>
Граница JS ↔ WASM: память и FFI
- Общая память — это один большой ArrayBuffer (
WebAssembly.Memory). - Передаём только числа (i32, f64) или указатели в память.
- Для строк/структур используем копирование в/из Linear Memory.
- Скорость вызова: ~0.5 µs на переход, что в 5–10 раз дешевле JNI в Android.
Реальные кейсы
- AutoCAD Web — полноценный CAD в браузере (порт 35 млн строк C++).
- Unity WebGL — игровой движок компилируется в WASM.
- Figma — движок рендеринга на C++ под капотом.
- Photoshop для web — бетта уже на WASM + WebGL.
Сколько весит runtime
- Минимальный модуль: 500 байт.
- Emscripten runtime: +70 КБ gzip (malloc, libc, glue).
- Rust
wasm-pack: ~15 КБ gzip при--no-modules.
Ограничения
- Нет прямого доступа к DOM (только через JS).
- Нет потоков (SharedArrayBuffer + Atomics возвращаются, но нужны заголовки COOP/COEP).
- Размер Linear Memory ограничен 4 ГБ (32-битные указатели).
- Отладка: source-maps есть, но всё ещё проще gdb → printf.
Будущее
- WebAssembly 2.0 — 64-битная память, SIMD, исключения, GC.
- WASI — системный интерфейс для запуска WASM вне браузера (edge, IoT).
- Component Model — универсальные ABI-библиотеки между языками.
Итого
WASM — это не замена JavaScript, а его «задняя передача» для тяжёлых вычислений. Если вашей задачи хватает JS — оставайтесь на нём. Если нужен Photoshop-уровень производительности — компилируйте в WASM и наслаждайтесь почти родной скоростью в любой вкладке.
Полезные ресурсы
-
У вас нет разрешения на просмотр ссылки, пожалуйста Вход или Регистрация
-
У вас нет разрешения на просмотр ссылки, пожалуйста Вход или Регистрация
-
У вас нет разрешения на просмотр ссылки, пожалуйста Вход или Регистрация
-
У вас нет разрешения на просмотр ссылки, пожалуйста Вход или Регистрация