WebAssembly

Материал из llmdocs — справочник разработчика
Портал: Go и Rust
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 и компонентной модели ещё развивается.

См. также

Источники

  1. WebAssembly — официальный сайт
  2. WebAssembly Specification
  3. MDN — WebAssembly
  4. W3C — World Wide Web Consortium (W3C) brings a new language to the Web as WebAssembly becomes a W3C Recommendation (2019)
  5. A. Haas et al. — Bringing the Web up to Speed with WebAssembly (PLDI 2017)
  6. WASI — WebAssembly System Interface