BlazorMiddleExperience

Какие архитектурные решения Blazor навязывает вокруг rendering, state, routing, styling, data loading или deployment?

Blazor навязывает выбор модели рендеринга (Server/WASM/Auto), управление состоянием через DI-сервисы, маршруты через @page, CSS Isolation и жёсткую привязку деплоя к модели хостинга.

Архитектурные решения, которые навязывает Blazor

Blazor — это фреймворк Microsoft для построения интерактивных веб-интерфейсов на C# вместо JavaScript. В зависимости от выбранной модели хостинга он накладывает разные ограничения и соглашения.

Rendering

Blazor предлагает три модели рендеринга, и выбор нужно сделать на старте проекта:

  • Blazor Server — весь UI-рендеринг происходит на сервере через SignalR. Браузер получает только diff DOM-патчи. Минус: задержка на каждое взаимодействие, постоянный WebSocket.
  • Blazor WebAssembly (WASM) — .NET-рантайм скачивается в браузер (~10 MB), рендеринг происходит на клиенте. Минус: большой initial payload, холодный старт.
  • Blazor United / Auto (с .NET 8) — начинает как Server, переключается на WASM после загрузки. Render-режим задаётся атрибутом @rendermode.
// Pages/Counter.razor
@page "/counter"
@rendermode InteractiveWebAssembly

<h1>Counter: @count</h1>
<button @onclick="Increment">+1</button>

@code {
    private int count = 0;
    private void Increment() => count++;
}

State

Blazor не имеет встроенного глобального стейт-менеджера уровня Redux. Стандартные подходы:

  • Сервисы через DI (AddScoped для Server, AddSingleton для WASM-клиента).
  • Каскадные параметры (CascadingValue / CascadingParameter) для передачи состояния вниз по дереву компонентов.
  • Библиотека Fluxor для Flux/Redux-подхода, если нужна предсказуемость.

Routing

Маршруты задаются директивой @page прямо в .razor-файле. Router настраивается в App.razor. Поддерживаются параметры (/jobs/{id:int}), query-строки через [SupplyParameterFromQuery] (с .NET 7), lazy-loaded assemblies.

Styling

Blazor использует CSS Isolation: файл Component.razor.css автоматически скопирован и изолирован. Стили компилируются в бандл с уникальными атрибутами (b-xxxxxxxx). Глобальные стили — в wwwroot/app.css. Tailwind и Bootstrap подключаются стандартно через CDN или npm-пайплайн.

Data Loading

Данные обычно загружаются в OnInitializedAsync(). В Blazor Server можно вызывать EF Core напрямую из компонента. В WASM — только через HTTP к API. С .NET 8 появился StreamRendering для потоковой загрузки страниц, как в Next.js.

@inject HttpClient Http

@code {
    private Job[]? jobs;

    protected override async Task OnInitializedAsync()
    {
        jobs = await Http.GetFromJsonAsync<Job[]>("/api/jobs");
    }
}

Deployment

  • Blazor Server: требует постоянный .NET-хост (ASP.NET Core), SignalR, сессии на сервере. Не работает за stateless CDN.
  • Blazor WASM: статические файлы — деплоится на GitHub Pages, Azure Static Web Apps, Netlify. Backend нужен отдельно.
  • Blazor Hybrid (MAUI): упакован в нативное приложение — iOS, Android, macOS, Windows.

Подводные камни

  • Выбор модели рендеринга нельзя легко поменять на полпути — это фундаментальное архитектурное решение.
  • Blazor WASM имеет холодный старт 3–10 секунд из-за загрузки .NET-рантайма; AOT-компиляция ускоряет выполнение, но ещё больше раздувает бандл.
  • Blazor Server не масштабируется горизонтально без Sticky Sessions или распределённого кэша SignalR (например, через Azure SignalR Service).
  • CSS Isolation не работает для динамически добавляемых через JS элементов — атрибут b-xxxxxxxx не применится.
  • DI-время жизни (Scoped vs Singleton) кардинально отличается между Server и WASM — ошибки в этом месте ведут к утечкам состояния.
  • EF Core DbContext нельзя использовать как Singleton в Blazor Server — каждый circuit должен получать свой Scoped экземпляр.
  • Отсутствие встроенного SSR с гидратацией: до .NET 8 SEO-индексирование Blazor WASM было практически нулевым.
  • Отладка WASM в браузере требует специальной настройки launch-профиля и Chrome DevTools; не всегда удобна по сравнению с обычным JavaScript.

What hurts your answer

  • Знать термины Blazor, но не понимать связи между абстракциями
  • Объяснять поведение через отдельные примеры вместо причинной модели
  • Не связывать mental model с диагностикой ошибок

What they're listening for

  • Понимает ключевые абстракции Blazor
  • Может предсказывать поведение системы через mental model
  • Связывает модель с debugging и production decisions

Related topics