Какие архитектурные решения 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-время жизни (
ScopedvsSingleton) кардинально отличается между 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