Blazor (.NET 8+) offers multiple render modes, each with different performance characteristics and capabilities. Choosing the wrong render mode can lead to poor user experience, unnecessary server load, or missed opportunities for interactivity.
Understanding the strengths and trade-offs of each render mode helps you make informed architectural decisions. For comprehensive details, see Blazor render modes on Microsoft Learn.
Renders pages on the server and sends static HTML to the client. No interactivity after initial render.
Use when:
✅ Benefits:
❌ Drawbacks:
@page "/about"@rendermode RenderMode.InteractiveServer<h1>About Us</h1><p>This is a static page with no interactivity.</p>
❌ Figure: Bad example - Using InteractiveServer for a static page wastes server resources
@page "/about"<h1>About Us</h1><p>This is a static page with no interactivity.</p>
✅ Figure: Good example - Static SSR (default) is perfect for content-only pages
Maintains a SignalR connection to the server. UI updates are sent over the connection in real-time.
Use when:
✅ Benefits:
❌ Drawbacks:
@page "/counter"@rendermode InteractiveServer<h1>Counter</h1><p>Current count: @currentCount</p><button @onclick="IncrementCount">Click me</button>@code {private int currentCount = 0;private void IncrementCount(){currentCount++;}}
✅ Figure: Good example - Interactive Server for real-time features
Runs entirely in the browser using WebAssembly. No server connection needed after initial load.
Use when:
✅ Benefits:
❌ Drawbacks:
@page "/game"@rendermode InteractiveWebAssembly<h1>Browser-Based Game</h1><p>Score: @score</p><button @onclick="Play">Play</button>@code {private int score = 0;private void Play(){// Runs entirely in browserscore += Random.Shared.Next(1, 10);}}
✅ Figure: Good example - WebAssembly for offline-capable or compute-intensive UI
Starts with Interactive Server, then upgrades to WebAssembly on subsequent visits (after downloading).
Use when:
✅ Benefits:
❌ Drawbacks:
@page "/dashboard"@rendermode InteractiveAuto<h1>Dashboard</h1><Chart Data="@chartData" />@code {private ChartData? chartData;protected override async Task OnInitializedAsync(){chartData = await LoadDataAsync();}}
✅ Figure: Good example - Auto mode for progressive web apps
You can mix render modes within the same application:
@* Static page with interactive components *@@page "/products"<h1>Our Products</h1>@* Static product list *@<ProductList />@* Interactive search *@<ProductSearch @rendermode="InteractiveServer" />@* Interactive shopping cart *@<ShoppingCart @rendermode="InteractiveWebAssembly" />
✅ Figure: Good example - Using the right render mode for each component