WebAssembly и Rust: что это и зачем вам об этом знать

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Вступление: когда JavaScript перестаёт справляться

Мы привыкли, что весь интернет держится на JavaScript. Он гибок, прощает ошибки и работает везде. Но есть задачи, где даже самый оптимизированный JS-код начинает «тормозить»: обработка видео, 3D-рендеринг, сложные алгоритмы, игры. И тогда на сцену выходят WebAssembly и Rust — дуэт, который даёт веб-приложениям скорость нативного кода.

В этой статье мы разберём, что такое WebAssembly, почему Rust для Wasm — один из лучших выборов, и как написать свой первый модуль на Rust, который будет работать в браузере. Статья будет полезна как новичкам, так и тем, кто уже слышал про Wasm Rust, но не знает, с какой стороны подойти.

Что такое WebAssembly (Wasm)?

WebAssembly — это бинарный формат инструкций, который выполняется в браузере со скоростью, близкой к нативной. Проще говоря, это низкоуровневый «виртуальный процессор» для веба. Браузер загружает компактный .wasm-файл и исполняет его напрямую, минуя интерпретатор JavaScript.

Ключевые особенности Wasm:

  • Высокая производительность — код выполняется почти так же быстро, как скомпилированный C++ или Rust.
  • Безопасность — Wasm работает в изолированной песочнице, как и JS.
  • Компактность — .wasm-файлы обычно весят в разы меньше, чем аналогичный JS-код.
  • Переносимость — один и тот же модуль работает во всех современных браузерах.

Но Wasm — это не замена JavaScript. Это инструмент для задач, где JS слаб. Вы пишете критичный по скорости код на Rust, компилируете в Wasm, а JS служит «клеем», который вызывает этот модуль.

Почему именно Rust для WebAssembly?

Выбор языка для компиляции в Wasm — не принципиален. Можно использовать C, C++, Go, даже Python (через Pyodide). Но Rust для WebAssembly стал стандартом де-факто. Почему?

1. Безопасность памяти без сборщика мусора

Rust — единственный популярный системный язык, который гарантирует безопасность памяти на этапе компиляции. В отличие от C/C++, вы не получите segfault в рантайме. А отсутствие сборщика мусора (GC) означает, что у вас нет внезапных «фризов» — идеально для real-time приложений.

2. Нулевая стоимость абстракций

Вы пишете высокоуровневый код с итераторами, замыканиями и трейтами, но компилятор Rust превращает его в машинный код, который не уступает рукописному ассемблеру. Это даёт производительность C++ с удобством современных языков.

3. Экосистема wasm-pack и wasm-bindgen

Инструменты для компиляции Rust в Wasm доведены до ума. wasm-pack собирает проект, генерирует JS-обёртки и даже публикует пакет в npm. wasm-bindgen позволяет легко передавать строки, массивы и объекты между Rust и JavaScript.

4. Маленький размер выходного файла

Rust компилируется в Wasm без рантайма. Вы получаете минимальный бинарник. Даже с учётом стандартной библиотеки (через wasm-pack) размер редко превышает 50-100 КБ для реальных задач.

Как это работает: пишем первый модуль на Rust для Wasm

Давайте создадим простой модуль, который конвертирует градусы Цельсия в Фаренгейты и обратно. Это покажет вам всю цепочку: код на Rust → Wasm → вызов из JavaScript.

Шаг 1. Установка инструментов

Вам понадобится Rust (установите через rustup) и wasm-pack:

curl https://sh.rustup.rs -sSf | sh
# Установка wasm-pack
cargo install wasm-pack

Шаг 2. Создаём проект

cargo new --lib temp-converter
cd temp-converter

Откройте Cargo.toml и добавьте:

[lib]
crate-type = ["cdylib"]

[dependencies]
wasm-bindgen = "0.2"

Флаг cdylib говорит компилятору создать динамическую библиотеку — то, что нужно для Wasm.

Шаг 3. Пишем код на Rust

В файле src/lib.rs напишем:

use wasm_bindgen::prelude::*;

/// Конвертирует Цельсий в Фаренгейты
#[wasm_bindgen]
pub fn celsius_to_fahrenheit(c: f64) -> f64 {
    c * 9.0 / 5.0 + 32.0
}

/// Конвертирует Фаренгейты в Цельсий
#[wasm_bindgen]
pub fn fahrenheit_to_celsius(f: f64) -> f64 {
    (f - 32.0) * 5.0 / 9.0
}

/// Возвращает строку с приветствием — показывает работу со строками
#[wasm_bindgen]
pub fn greet(name: &str) -> String {
    format!("Привет, {}! Температура в C: {:.1}°C", name, 25.0)
}

Макрос #[wasm_bindgen] — ключевой. Он автоматически генерирует JS-обёртку для каждой функции. Rust-строки (String) и &str корректно преобразуются в JavaScript-строки.

Шаг 4. Компилируем в Wasm

wasm-pack build --target web

После выполнения в папке pkg появятся файлы: temp_converter_bg.wasm (бинарник) и temp_converter.js (JS-обёртка).

Шаг 5. Используем в HTML

Создайте index.html в корне проекта:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Rust + Wasm: Конвертер температур</title>
</head>
<body>
    <h2>Конвертер температур на Rust</h2>
    <p id="result"></p>

    <script type="module">
        import init, { celsius_to_fahrenheit, fahrenheit_to_celsius, greet } from './pkg/temp_converter.js';

        async function run() {
            await init(); // Загружаем Wasm-модуль

            const c = 25.0;
            const f = celsius_to_fahrenheit(c);
            const back = fahrenheit_to_celsius(f);

            document.getElementById('result').innerHTML = `
                <b>${c}°C = ${f.toFixed(1)}°F</b><br>
                <b>${f.toFixed(1)}°F = ${back                

Блоги

Рекомендаций по книгам