WebAssembly и C#: Зачем это нужно современному разработчику

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

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

Начать курс

Когда C# встречает WebAssembly: новая эра веб-разработки

Представьте себе мир, где вы можете взять свой любимый C#, написать сложный алгоритм обработки изображений, скомпилировать его и запустить прямо в браузере — с производительностью, близкой к нативной. Звучит как научная фантастика? А вот и нет. Это WebAssembly (или просто Wasm) — технология, которая переворачивает представление о том, что можно делать в вебе.

Я сам был скептиком, пока не попробовал. Долгое время казалось, что JavaScript — единственный язык для браузера. Но времена меняются. Сегодня мы, C#-разработчики, можем выйти за пределы серверной части и строить полноценные клиентские приложения на родном языке. В этой статье я покажу вам, как это работает, зачем это нужно и приведу реальные примеры кода.

Что такое WebAssembly простыми словами

Давайте без сложных терминов. WebAssembly — это низкоуровневый бинарный формат инструкций, который выполняется в браузере почти с нативной скоростью. В отличие от JavaScript, который интерпретируется, Wasm компилируется заранее. Это как если бы вы запускали программу на C++ прямо в браузере, но с песочницей безопасности.

Как это связано с C#?

Ваш C#-код может быть скомпилирован в WebAssembly. Вы пишете на привычном языке, используете .NET-библиотеки, а на выходе получаете файл .wasm, который браузер выполняет. Для этого существует несколько подходов, но самый популярный — Blazor WebAssembly.

  • Blazor WebAssembly — фреймворк от Microsoft, который запускает .NET в браузере.
  • Mono Wasm Runtime — среда выполнения .NET, скомпилированная в Wasm.
  • NativeAOT-ot — экспериментальный режим компиляции C# напрямую в Wasm без рантайма.

Зачем вообще использовать C# в браузере?

Хороший вопрос. Ведь есть JavaScript, TypeScript, наконец. Зачем нам C#? Ответ кроется в трёх вещах: производительность, безопасность и экосистема.

1. Производительность для тяжелых вычислений

JavaScript хорош, но для обработки видео, криптографии, симуляций или парсинга больших данных он медленнее. WebAssembly на C# может быть в 10-20 раз быстрее для некоторых задач. Например, если вы пишете редактор изображений на C#, он будет работать в браузере так же быстро, как настольное приложение.

2. Повторное использование кода

У вас есть библиотека на C# для валидации данных на сервере? Просто возьмите и используйте её на клиенте. Никакого дублирования логики на JavaScript. Это снижает количество багов и ускоряет разработку.

3. Безопасность типов

C# — строго типизированный язык. Многие ошибки, которые вылавливаются в рантайме на JavaScript, в C# отлавливаются на этапе компиляции. Для сложных бизнес-приложений это критично.

Практический пример: компиляция C# в WebAssembly

Давайте напишем простую программу на C#, которая вычисляет факториал, и запустим её в браузере. Для этого используем Blazor WebAssembly.

Шаг 1: Создаем проект

dotnet new blazorwasm -o WasmFactorial
cd WasmFactorial

Это создаст стандартный шаблон Blazor WebAssembly. В нём уже есть всё необходимое: рантайм .NET, скомпилированный в Wasm, и мост для взаимодействия с JavaScript.

Шаг 2: Пишем C#-код для вычислений

Добавим сервис для вычисления факториала. Создадим файл Services/FactorialService.cs:

namespace WasmFactorial.Services;

public class FactorialService
{
    public long Calculate(int n)
    {
        if (n < 0) throw new ArgumentException("Число должно быть неотрицательным");
        if (n == 0) return 1;
        
        long result = 1;
        for (int i = 1; i <= n; i++)
        {
            result *= i;
        }
        return result;
    }
    
    // Демонстрация сложной логики, которая медленна в JS
    public double ComputePi(int iterations)
    {
        double pi = 0.0;
        for (int i = 0; i < iterations; i++)
        {
            pi += (i % 2 == 0 ? 1.0 : -1.0) / (2 * i + 1);
        }
        return pi * 4;
    }
}

Шаг 3: Используем сервис в компоненте Blazor

Теперь создадим страницу, где пользователь вводит число и получает результат. Откроем Pages/Factorial.razor:

@page "/factorial"
@inject FactorialService FactorialService

<h3>Вычисление факториала на C# в браузере</h3>

<div class="form-group">
    <label for="number">Введите число (0-20):</label>
    <input type="number" id="number" @bind="inputNumber" min="0" max="20" />
    <button class="btn btn-primary" @onclick="CalculateFactorial">
        Вычислить
    </button>
</div>

@if (result.HasValue)
{
    <div class="alert alert-success">
        Факториал числа @inputNumber равен: @result
    </div>
}
@if (errorMessage != null)
{
    <div class="alert alert-danger">
        @errorMessage
    </div>
}

@code {
    private int inputNumber = 5;
    private long? result;
    private string? errorMessage;

    private void CalculateFactorial()
    {
        try
        {
            result = FactorialService.Calculate(inputNumber);
            errorMessage = null;
        }
        catch (Exception ex)
        {
            errorMessage = ex.Message;
            result = null;
        }
    }
}

Запустите проект командой dotnet run и откройте браузер. Вся логика выполняется на стороне клиента, в WebAssembly. Никакого сервера для вычислений не нужно!

Как это работает под капотом

Когда вы запускаете Blazor WebAssembly, происходит следующее:

  1. Браузер загружает файл dotnet.wasm — это среда выполнения .NET, скомпилированная в WebAssembly.
  2. Загружаются ваши сборки DLL (скомпилированный C#-код).
  3. Mono-рантайм исполняет ваш код, используя JIT-компиляцию или интерпретацию (зависит от настроек).
  4. Взаимодействие с DOM происходит через JavaScript-интероп.

Обратите внимание: загрузка рантайма (~2-3 МБ) — это плата за возможность писать на C#. Но для сложных приложений это окупается производительностью и удобством.

Когда стоит использовать WebAssembly с C#

Не всё так радужно. WebAssembly —

Блоги

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