WebAssembly
| Тип | двоичный формат инструкций для стековой виртуальной машины |
|---|---|
| Разработчики | W3C WebAssembly Community Group (Mozilla, Google, Microsoft, Apple и др.) |
| Анонс | 2015 |
| Поддержка в браузерах | 2017 (MVP) |
| Рекомендация W3C | декабрь 2019 |
| Вне браузера | WASI, среды wasmtime, Wasmer, WasmEdge |
| Исходные языки | Rust, C, C++, Go, Zig, C#, Kotlin и др. |
| Форматы | двоичный .wasm, текстовый .wat |
WebAssembly (сокращённо Wasm) — переносимый двоичный формат инструкций для виртуальной машины, позволяющий выполнять в браузере код, скомпилированный из Rust, C, C++, Go и других языков, со скоростью, близкой к нативной. Wasm работает в той же песочнице, что и JavaScript, и дополняет его там, где нужна производительность: обработка изображений и видео, игры, CAD-системы, криптография, запуск языковых моделей и баз данных прямо в браузере.
За пределами браузера WebAssembly используется как лёгкая и безопасная среда выполнения для плагинов, бессерверных функций и пограничных вычислений.
История
Попытки ускорить веб предпринимались давно: Google Native Client (NaCl) выполнял машинный код в песочнице, а Mozilla asm.js — строгое подмножество JavaScript, которое движки умели оптимизировать. В 2015 году инженеры Mozilla, Google, Microsoft и Apple объявили о совместной работе над новым форматом, вобравшим опыт обоих подходов. В 2017 году минимальная версия (MVP) появилась во всех основных браузерах, тогда же вышла статья с описанием дизайна.[5] В декабре 2019 года W3C утвердил WebAssembly как рекомендацию — четвёртый язык веба после HTML, CSS и JavaScript.[4]
Затем стандарт расширялся: SIMD, потоки и разделяемая память, подсчёт ссылок на объекты хоста, хвостовые вызовы, исключения, встроенная сборка мусора для управляемых языков (Kotlin, Java, Dart) и 64-битная память.[2]
Как устроен
- Стековая виртуальная машина с небольшим набором инструкций над целыми и дробными числами; код проверяется перед выполнением и компилируется движком в машинный код.
- Линейная память — непрерывный массив байтов, к которому модуль обращается по смещениям; выйти за её пределы невозможно.
- Модули импортируют функции из окружения (например, JavaScript-функции браузера) и экспортируют свои. Сам по себе Wasm не имеет доступа к DOM, сети или файлам — только к тому, что явно передал хост.
- Форматы: компактный двоичный
.wasmи текстовый.watдля чтения и отладки.
(module
(func (export "add") (param i32 i32) (result i32)
local.get 0
local.get 1
i32.add))
Пример: Rust в браузере
// src/lib.rs
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
pub fn fib(n: u32) -> u64 {
let (mut a, mut b) = (0u64, 1u64);
for _ in 0..n { (a, b) = (b, a + b); }
a
}
cargo install wasm-pack
wasm-pack build --target web # собирает .wasm и обёртку на JavaScript
import init, { fib } from "./pkg/my_lib.js";
await init();
console.log(fib(90)); // вычисление внутри WebAssembly
Инструмент wasm-bindgen генерирует связующий код между Rust и JavaScript, преобразуя строки, массивы и объекты. Для C и C++ ту же роль играет Emscripten, а Go компилирует в Wasm встроенными средствами (GOOS=js GOARCH=wasm) и через TinyGo.[3]
За пределами браузера
WASI (WebAssembly System Interface) — стандартный интерфейс для доступа Wasm-модулей к файлам, часам, сети и случайным числам вне браузера.[6] Он построен на принципе возможностей: модуль получает доступ только к тому, что ему явно выдали (например, к одному каталогу). Компонентная модель позволяет собирать приложения из модулей, написанных на разных языках, с типизированными интерфейсами.
Применения:
- Плагины — расширения для приложений и прокси (Envoy, Zed, Figma) без риска для хост-программы.
- Пограничные и бессерверные функции — Cloudflare Workers, Fastly Compute: холодный старт за микросекунды против сотен миллисекунд у контейнеров.
- Песочница для недоверенного кода — в том числе для кода, сгенерированного языковыми моделями.
- Переносимые утилиты — один
.wasmработает на любой ОС и архитектуре.
Среды выполнения вне браузера: wasmtime (Bytecode Alliance), Wasmer, WasmEdge. Docker умеет запускать Wasm-модули рядом с контейнерами.
Ограничения
- Wasm не заменяет JavaScript: доступ к DOM идёт через JavaScript, и частые переходы через границу «JS — Wasm» стоят времени.
- Размер модулей языков со сборкой мусора и большой стандартной библиотекой может быть значительным; Rust, C и Zig дают компактные модули.
- Отладка и профилирование сложнее, чем для JavaScript, хотя инструменты браузеров быстро улучшаются.
- Экосистема WASI и компонентной модели ещё развивается.
См. также
Источники
- WebAssembly — официальный сайт
- WebAssembly Specification
- MDN — WebAssembly
- W3C — World Wide Web Consortium (W3C) brings a new language to the Web as WebAssembly becomes a W3C Recommendation (2019)
- A. Haas et al. — Bringing the Web up to Speed with WebAssembly (PLDI 2017)
- WASI — WebAssembly System Interface