Go и AssemblyScript в Wasm
Смотрим на два других популярных пути компиляции в Wasm.
AssemblyScript — это язык, похожий на TypeScript, который компилируется прямо в Wasm; Go компилируется со своим рантаймом и GC.
Go: привычный язык, но с весом
Go умеет компилировать в Wasm командой с особыми переменными окружения. Это удобно: вы пишете обычный Go и получаете .wasm. Но есть нюанс — у Go есть сборщик мусора и рантайм планировщика горутин, и всё это компилируется в модуль. Поэтому модули Go тяжелее, чем у Rust или C.
GOOS=js GOARCH=wasm go build -o main.wasm main.go
# Go тащит свой рантайм и GC в .wasm — модуль крупнее
Существует также TinyGo — альтернативный компилятор, который даёт куда меньшие Wasm-модули за счёт урезанного рантайма, ценой поддержки не всех возможностей языка. Для embedded и Wasm TinyGo часто предпочтительнее.
AssemblyScript: TypeScript-подобный язык
AssemblyScript — отдельный язык, синтаксически почти неотличимый от TypeScript, но компилирующийся напрямую в Wasm. Он привлекателен для веб-разработчиков: знакомый синтаксис, но скорость Wasm. Платой за это является строгая статическая типизация и явные числовые типы. Исходник AssemblyScript помечаем language-text:
// AssemblyScript: похоже на TS, но типы i32 явные
export function add(a: i32, b: i32): i32 {
return a + b;
}
export function fib(n: i32): i32 {
if (n < 2) return n;
return fib(n - 1) + fib(n - 2);
}
Заметьте типы i32 вместо абстрактного number — AssemblyScript оперирует теми же четырьмя типами Wasm напрямую, поэтому компиляция предсказуема и быстра.
Проверим логику fib на JS
Алгоритм одинаков на любом языке. Повторим тот же Фибоначчи на чистом JS и убедимся в значениях:
function fib(n) {
if (n < 2) return n;
return fib(n - 1) + fib(n - 2);
}
console.log("fib(10) =", fib(10));
console.log("fib(15) =", fib(15));
Вывод:
fib(10) = 55 fib(15) = 610
Сравнение путей
| Язык | GC | Размер модуля | Когда выбрать |
| Rust | нет | малый | максимум скорости/компактности |
| C/C++ (Emscripten) | нет | средний | портирование готовых библиотек |
| Go | да | крупный | знаком, но вес терпим |
| AssemblyScript | да (свой) | малый-средний | веб-разработчику, знакомый синтаксис |
Как работает под капотом
Разница в размере модулей объясняется рантаймом. Rust и C не тащат сборщик мусора — в модуле почти только ваш код. Go включает свой GC и планировщик, поэтому даже пустая программа весит сотни килобайт. AssemblyScript имеет минималистичный собственный рантайм с GC, что держит модули небольшими. Выбор языка — это компромисс между знакомым синтаксисом и весом/скоростью результата.
Частые ошибки
- Удивляться размеру Go-модуля — это рантайм и GC; для лёгких задач берите TinyGo.
- Считать AssemblyScript «просто TypeScript» — это отдельный язык с явными типами и без многих возможностей TS.
- Игнорировать типы в AssemblyScript — абстрактный
numberтам не подойдёт, нужныi32/f64.
Итоги
- Go компилируется в Wasm, но тащит GC и рантайм — модули крупные (есть TinyGo).
- AssemblyScript — TS-подобный язык, компилируется прямо в Wasm, типы явные.
- Выбор языка — компромисс знакомства, веса и скорости.