Привет, коллеги. Я предприниматель и практик, который последние два года плотно работает с WebAssembly (WASM) в коммерческих проектах. И сегодня хочу разобрать новость, которая, на мой взгляд, переворачивает правила игры для всех, кто занимается высоконагруженными веб-приложениями, edge-вычислениями или просто хочет выжать максимум из браузера. Речь об асинхронности в WebAssembly.
Долгое время WASM был отличным инструментом для числодробилок и компиляции кода с C++/Rust, но у него был серьёзный недостаток — блокирующее выполнение. Если ваш WASM-модуль делал запрос к API или обращался к файловой системе, он вешал весь поток. Это было похоже на JavaScript в 2010 году, когда все сидели на колбэках и молились, чтобы сервер ответил быстрее. Но в июле 2026 года ситуация кардинально изменилась.
Согласно свежей публикации на Habr Источник, в экосистему WASM внедрена полноценная поддержка асинхронных операций на уровне стандарта. Это не просто очередной фреймворк — это изменение в спецификации самого WebAssembly. Давайте разберём, что это значит на практике, без воды и маркетинга.
Проблема: Почему WASM раньше был тормозом для I/O
До недавнего времени WASM работал по принципу «один поток — одна задача». Если вы писали модуль на Rust и компилировали его в WASM, любая операция ввода-вывода (чтение файла, HTTP-запрос, обращение к базе данных) блокировала весь поток выполнения. В JavaScript есть event loop, который элегантно решает эту проблему через async/await. В WASM же приходилось идти на ухищрения:
- Передавать управление обратно в JS — писать прослойку, которая вызывала WASM-функцию, ждала ответа от JS, а потом снова вызывала WASM. Это добавляло латентность и усложняло код.
- Использовать Web Workers — дробить логику на отдельные потоки, но это увеличивало потребление памяти и усложняло синхронизацию.
- Отказываться от WASM для I/O — многие просто делали вычисления в WASM, а все сетевые запросы оставляли на JS.
Я столкнулся с этим лично, когда мы писали парсер логов для внутреннего аналитического дашборда. Модуль на Rust (скомпилированный в WASM) обрабатывал 100 мегабайт логов за 200 миллисекунд — отлично. Но как только мы попытались загрузить эти логи по HTTP внутри WASM, всё вставало на паузу. Пришлось делать костыль: загружать данные через JS, передавать их в WASM, обрабатывать, возвращать результат. Дополнительные 50–100 мс на каждый чих.
Решение: Асинхронный WASM — как это работает
Новость, о которой пишет Habr, касается внедрения механизма асинхронных вызовов непосредственно в виртуальную машину WASM. Если кратко — теперь WASM-модуль может приостановить выполнение функции, не блокируя поток, дождаться ответа от внешнего источника (сеть, файловая система, другой модуль) и возобновить выполнение. Это реализовано через так называемые «asyncify»-подобные трансформации, но на уровне байткода.
Ключевые изменения, которые описаны в статье:
1. Поддержка async/await на уровне WASM — теперь можно компилировать код на Rust, C++ или Go с использованием асинхронных конструкций, и они будут работать внутри браузера без дополнительных обёрток.
2. Новый тип инструкции async_call — в байткоде появилась инструкция, которая позволяет приостановить выполнение текущей функции, передать управление рантайму и возобновить выполнение после завершения асинхронной операции.
3. Интеграция с JavaScript event loop — WASM-модули теперь могут «подписываться» на события из JS, не требуя callback-функций. Это снижает overhead на межъязыковое взаимодействие.
Для разработчиков это означает, что теперь можно писать серверную логику на Rust или Go, компилировать её в WASM и запускать в браузере с полноценной поддержкой асинхронности. Никаких больше «WASM только для CPU-задач».
Практический кейс: Переписываем микросервис на WASM
Я решил проверить это на реальном проекте. У нас был микросервис на Node.js, который отвечал за агрегацию данных из нескольких внешних API (погода, курсы валют, новости). Каждый запрос к микросервису делал 3–5 параллельных HTTP-запросов, обрабатывал JSON и возвращал агрегированный результат. Среднее время ответа — 120 мс.
Мы переписали этот микросервис на Rust с использованием асинхронного WASM и запустили его как Cloudflare Worker (они давно поддерживают WASM). Результаты до и после:
| Параметр | Node.js (исходный) | Rust + WASM (новый) |
|---|---|---|
| Среднее время ответа | 120 мс | 68 мс |
| Потребление памяти | 48 MB | 12 MB |
| Время холодного старта | 250 мс | 4 мс |
| Количество строк кода | 320 | 180 |
Выигрыш в скорости — почти 2 раза. Памяти — в 4 раза меньше. Холодный старт — практически мгновенный. И это без каких-либо оптимизаций — просто взяли код на Rust, добавили async перед функциями, скомпилировали в WASM и задеплоили.
Технические детали для прагматиков
Если вы решите попробовать асинхронный WASM на своих проектах, вот что нужно знать:
- Инструментарий — на момент июля 2026 года стабильная поддержка асинхронности есть в компиляторах
rustc(черезwasm-pack),emscripten(для C/C++) иtinygo(для Go). Для Go нужно быть аккуратным — у них своя модель горутин, которая не всегда хорошо ложится на WASM. - Рантаймы — асинхронный WASM работает во всех современных браузерах (Chrome 125+, Firefox 125+, Safari 18+) и в серверных рантаймах вроде Wasmtime и Wasmer (версии 15+). Cloudflare Workers и Fastly Compute@Edge уже обновили свои движки.
- Ограничения — не все библиотеки, которые используют блокирующие вызовы (например,
std::fsв Rust), будут работать асинхронно из коробки. Придётся переписать их на асинхронные аналоги. В Rust это библиотекиtokioиasync-std— они уже адаптированы.
Выводы: Кому это нужно прямо сейчас
Асинхронность в WASM — это не просто «ещё одна фича». Это снятие последнего серьёзного барьера для использования WASM в production. Если вы:
- Пишете edge-функции (Cloudflare Workers, Deno Deploy, Vercel Edge) — можете смело переходить на Rust/Go и получать выигрыш в производительности и памяти.
- Строите PWA с офлайн-обработкой данных — теперь можно загружать и обрабатывать файлы внутри WASM без костылей.
- Делаете библиотеки для работы с WebRTC, WebSockets или базами данных (IndexedDB) — асинхронный WASM позволит писать логику на одном языке и компилировать под все платформы.
Лично я уже перевёл два коммерческих проекта на асинхронный WASM. Первый — это парсер логов, о котором я говорил в начале. Теперь он загружает данные через HTTP прямо внутри WASM, без JS-прослойки. Второй — это внутренний инструмент для генерации отчётов, который раньше работал на Python (через Pyodide) и потреблял 200+ MB RAM. После переписывания на Rust + WASM он стал занимать 15 MB и работает в 10 раз быстрее.
Если вы всё ещё сомневаетесь — попробуйте сделать простой эксперимент. Возьмите любой свой микросервис, который делает HTTP-запросы, перепишите его на Rust с использованием reqwest (асинхронный HTTP-клиент) и скомпилируйте в WASM. Замерьте время ответа. Я уверен, результаты вас удивят.
Асинхронность в WebAssembly — это не будущее, это настоящее. Июль 2026 года — отличное время, чтобы начать использовать это в своих проектах.
Комментарии