# .NET 9 Blazor : Développement Full-Stack avec Blazor United en 2026
> .NET 9 Blazor United réunit le rendu statique SSR, le mode Server et WebAssembly dans un framework full-stack unifié. Un tutoriel pratique couvrant les modes de rendu, le streaming, l'injection par constructeur et les patterns de production.
- Published: 2026-04-26
- Updated: 2026-04-26
- Author: SharpSkill
- Tags: dotnet, blazor, aspnet-core, webassembly, full-stack
- Reading time: 8 min
---
Blazor United dans .NET 9 fusionne trois stratégies de rendu — le rendu statique côté serveur (SSR), le mode interactif Server et WebAssembly — au sein d'un même framework full-stack cohérent. Ce modèle unifié, introduit avec .NET 8 et perfectionné dans .NET 9, supprime la nécessité de choisir entre différents modèles d'hébergement Blazor avant même d'écrire la première ligne de code.
> **Blazor United en résumé**
>
> Blazor United permet de combiner le rendu statique SSR, l'interactivité Server et l'interactivité WebAssembly au sein de la même application. Chaque composant déclare indépendamment son mode de rendu, offrant un contrôle précis sur les performances et l'interactivité page par page.
## Mise en place d'une application Blazor Web avec .NET 9
Le template `blazorweb` de .NET 9 génère un projet préconfigué pour les trois modes de rendu. L'installation nécessite le SDK .NET 9 (version 9.0.100 ou ultérieure) et crée à la fois le projet serveur et le projet client (WASM) en une seule commande.
```bash
# Créer une nouvelle Blazor Web App avec tous les modes de rendu activés
dotnet new blazorweb -n FullStackApp --interactivity Auto --all-interactive false
cd FullStackApp
dotnet run
```
Le flag `--interactivity Auto` active les modes de rendu Server et WebAssembly. Le paramètre `--all-interactive false` conserve le rendu statique SSR par défaut, de sorte que l'interactivité est activée composant par composant plutôt que globalement.
## Comprendre les modes de rendu Blazor dans .NET 9
Chaque composant d'une Blazor Web App adopte un mode de rendu qui détermine où il s'exécute, s'il supporte l'interactivité et comment il communique avec le serveur. .NET 9 propose quatre modes distincts.
| Mode de rendu | Hébergement | Interactivité | Cas d'usage |
|---|---|---|---|
| SSR statique | Serveur | Aucune | Pages marketing, documentation, contenu SEO |
| Interactive Server | Serveur via SignalR | Complète | Tableaux de bord, CRUD, formulaires |
| Interactive WebAssembly | Navigateur via WASM | Complète | Mode hors ligne, logique client intensive |
| Interactive Auto | Serveur puis WASM | Complète | Le meilleur des deux — chargement rapide + autonomie |
Le mode de rendu est défini au niveau du composant avec la directive `@rendermode`. Cette granularité par composant signifie qu'une seule page peut mélanger des sections statiques et interactives.
```csharp
// Components/Pages/Dashboard.razor
@page "/dashboard"
@rendermode InteractiveServer
Dashboard
Real-Time Metrics
```
Une nouveauté de l'API .NET 9 — `ComponentBase.RendererInfo` — permet aux composants de détecter leur mode de rendu actuel à l'exécution, rendant possible une logique conditionnelle basée sur le contexte d'exécution.
```csharp
// Components/Shared/AdaptiveComponent.razor
@if (RendererInfo.IsInteractive)
{
}
else
{
Static Fallback Link
}
@code {
private void HandleClick()
{
// Runs only in interactive modes (Server or WASM)
}
}
```
## Le rendu en streaming pour les pages à forte charge asynchrone
Les pages SSR statiques qui récupèrent des données de manière asynchrone peuvent bloquer la réponse jusqu'à la fin de toutes les tâches. Le rendu en streaming résout ce problème en envoyant immédiatement du HTML de substitution, puis en transmettant le contenu définitif à mesure que les données arrivent. Dans .NET 9, l'attribut `[StreamRendering]` ne nécessite plus le paramètre `true` — il est activé par défaut.
```csharp
// Components/Pages/Products.razor
@page "/products"
@attribute [StreamRendering]
Product Catalog
@if (products is null)
{
Loading products...
}
else
{
@foreach (var product in products)
{
}
}
@code {
private List? products;
// Data loads asynchronously; streaming pushes updates to the browser
protected override async Task OnInitializedAsync()
{
products = await ProductService.GetAllAsync();
}
}
```
Le rendu en streaming repose sur le transfert par morceaux HTTP/1.1 (chunked transfer encoding), pris en charge par tous les navigateurs modernes. Le contenu de substitution s'affiche instantanément, et le balisage final le remplace sans rechargement complet de la page.
## Injection par constructeur dans les composants Blazor
.NET 9 introduit l'injection par constructeur pour les composants Blazor, complétant la directive `@inject` et l'attribut `[Inject]` existants. Combinée aux constructeurs primaires de C# 12, les dépendances de services deviennent partie intégrante de la signature du composant.
```csharp
// Components/Pages/OrderHistory.razor
@page "/orders"
@rendermode InteractiveServer
Order History
@if (orders is not null)
{
Order ID
Date
Total
@foreach (var order in orders)
{
@order.Id
@order.PlacedAt.ToShortDateString()
@order.Total.ToString("C")
}
}
@code {
// Constructor injection via primary constructor
[Inject] public required IOrderService OrderService { get; set; }
[Inject] public required NavigationManager Nav { get; set; }
private List? orders;
protected override async Task OnInitializedAsync()
{
orders = await OrderService.GetRecentOrdersAsync();
}
}
```
L'injection par constructeur rend les dépendances explicites et simplifie les tests unitaires. Les services enregistrés dans `Program.cs` sont résolus automatiquement, y compris les services à clé ajoutés via `builder.Services.AddKeyedScoped()`.
## Le mode Interactive Auto — le meilleur des deux mondes
Le mode Auto offre le temps de chargement perçu le plus rapide. Lors de la première visite, le composant s'exécute sur le serveur via SignalR pendant que le runtime WebAssembly se télécharge en arrière-plan. Lors des visites suivantes, l'exécution bascule entièrement vers le navigateur.
```csharp
// Components/Pages/Chat.razor
@page "/chat"
@rendermode InteractiveAuto
Live Chat
@foreach (var msg in messages)
{
@msg.Author: @msg.Text
}
@code {
[Inject] public required IChatService ChatService { get; set; }
private List messages = new();
private string newMessage = string.Empty;
protected override async Task OnInitializedAsync()
{
messages = await ChatService.GetRecentMessagesAsync();
}
private async Task HandleKey(KeyboardEventArgs e)
{
if (e.Key == "Enter" && !string.IsNullOrWhiteSpace(newMessage))
{
await ChatService.SendAsync(newMessage);
newMessage = string.Empty;
}
}
}
```
Le mode Auto exige que les dépendances et la logique du composant fonctionnent dans les deux contextes, serveur et WASM. Les services doivent être abstraits derrière des interfaces et enregistrés dans les conteneurs d'injection de dépendances du serveur et du client.
## Reconnexion et résilience dans .NET 9
.NET 9 réécrit la logique de reconnexion de Blazor Server avec une stratégie de backoff exponentiel. Au lieu de réessayer à intervalles fixes, le framework commence par des tentatives rapides puis augmente progressivement le délai — réduisant la charge serveur lors des pannes tout en récupérant rapidement après de brèves interruptions.
Améliorations clés :
- Revenir sur un onglet déclenche une tentative de reconnexion immédiate
- Si le serveur a déjà libéré le circuit, la page se rafraîchit automatiquement
- L'interface par défaut affiche « Reconnexion au serveur... » avec un indicateur de progression
- Les intervalles de nouvelle tentative sont configurables via `Blazor.start()`
```javascript
// wwwroot/app.js — Custom reconnection configuration
Blazor.start({
circuit: {
reconnectionOptions: {
retryIntervalMilliseconds: (retryNumber) => {
// Exponential backoff: 200ms, 400ms, 800ms, max 30s
return Math.min(200 * Math.pow(2, retryNumber), 30000);
},
maxRetries: 15
}
}
});
```
## SSR statique avec interactivité sélective
L'architecture recommandée pour la plupart des Blazor Web Apps en 2026 commence par le SSR statique par défaut, en ajoutant l'interactivité uniquement là où c'est nécessaire. L'attribut `[ExcludeFromInteractiveRouting]` (nouveauté .NET 9) marque les pages qui doivent rester statiques — utile pour les pages qui dépendent de cookies HTTP ou du cycle requête/réponse.
```csharp
// Components/Pages/Privacy.razor
@page "/privacy"
@attribute [ExcludeFromInteractiveRouting]
Privacy Policy
Privacy Policy
Last updated: April 2026
```
Ce pattern fonctionne bien avec `MapStaticAssets`, un nouveau middleware .NET 9 qui compresse et « fingerprinte » les fichiers statiques au moment du build, remplaçant l'ancienne approche `UseStaticFiles` par une livraison optimisée prête à l'emploi.
## Gains de performances avec la compilation AOT de .NET 9
.NET 9 AOT (Ahead-of-Time) réduit la taille des payloads WebAssembly jusqu'à 40 % par rapport à .NET 8. Le démarrage de Blazor WASM est 25 % plus rapide selon les benchmarks Google Lighthouse. Ces gains s'appliquent automatiquement lors de la publication avec AOT activé.
```bash
# Publish with AOT for production
dotnet publish -c Release -p:RunAOTCompilation=true
```
La compression WebSocket est également activée par défaut pour les composants interactifs Server. Une Content Security Policy (`frame-ancestors: 'self'`) est appliquée automatiquement pour atténuer les vecteurs d'attaque liés à la compression.
## Conclusion
- Blazor United dans .NET 9 élimine le choix du modèle d'hébergement en combinant SSR statique, Server et WebAssembly dans un seul projet
- Les modes de rendu se définissent par composant avec `@rendermode` pour optimiser chaque page indépendamment — statique pour le SEO, Server pour les tableaux de bord, Auto pour les scénarios hybrides
- Le rendu en streaming avec `[StreamRendering]` supprime les délais de chargement sur les pages à forte charge asynchrone
- L'injection par constructeur (nouveauté .NET 9) rend les dépendances des composants explicites et testables
- Le mode Auto offre un premier affichage rapide via Server, puis bascule sur WASM pour une indépendance totale côté client
- Le backoff exponentiel pour la reconnexion réduit les connexions perdues et élimine les rafraîchissements manuels
- La compilation AOT réduit la taille des payloads WASM de 40 % et le temps de démarrage de 25 %
- Toute Blazor Web App devrait démarrer avec le SSR statique par défaut, puis ajouter l'interactivité là où l'expérience utilisateur l'exige
---
Source: SharpSkill (https://sharpskill.dev), tech interview preparation for your real stack.
HTML version of this page: https://sharpskill.dev/fr/blog/dotnet/dotnet-9-blazor-united-full-stack-development