Start Debugging

Blazor Server vs Blazor WebAssembly vs Blazor United en .NET 11: ¿cuál elegir en 2026?

Para cualquier app Blazor nueva en .NET 11, crea un Blazor Web App (la plantilla antes apodada Blazor United) y elige el modo de render por página. Las plantillas Server-only o WebAssembly-only solo siguen teniendo sentido en casos puntuales.

Para un proyecto Blazor nuevo en .NET 11, la respuesta es la plantilla Blazor Web App (el modelo apodado “Blazor United” cuando .NET 8 estaba en preview). Te permite decidir el renderizado por componente: renderizado estático del servidor para páginas de marketing, Server interactivo para pantallas CRUD de baja latencia, WebAssembly interactivo para widgets con capacidad offline, y Auto para componentes que deben pasar de Server a WebAssembly cuando el payload de WASM termine de descargarse. Elige una plantilla solo Server o solo WebAssembly únicamente si tienes una restricción que descarte el modelo unificado: una app interna donde la descarga de WebAssembly sea inviable, o una PWA que deba funcionar totalmente offline contra una API de terceros.

Este artículo apunta a .NET 11 (en preview al momento de escribir, GA prevista para noviembre de 2026) y al conjunto de paquetes Microsoft.AspNetCore.Components 11.0.x. Las plantillas de proyecto provienen de Microsoft.AspNetCore.Components.WebAssembly.Templates y de la plantilla dotnet new blazor incluida en el SDK de .NET 11. Donde el comportamiento varíe entre versiones, indico las diferencias entre .NET 8, .NET 9, .NET 10 y .NET 11 de forma inline.

Qué es realmente “Blazor United” en .NET 11

“Blazor United” no es un modelo de hosting separado. Era el nombre de trabajo que Microsoft usó durante el ciclo de preview de .NET 8 para lo que finalmente se publicó como la plantilla Blazor Web App. La plantilla combina cuatro modos de render en un solo proyecto:

Declaras el modo por componente con @rendermode InteractiveServer, @rendermode InteractiveWebAssembly o @rendermode InteractiveAuto. El mismo archivo .razor puede correr en cualquiera de esos modos si no llama a APIs específicas del modo (más sobre esto abajo).

Blazor Server (la plantilla autónoma, dotnet new blazorserver) y Blazor WebAssembly (dotnet new blazorwasm) siguen existiendo en .NET 11, pero la guía de Microsoft desde .NET 8 ha sido: prefiere la plantilla unificada Blazor Web App salvo que tengas una razón específica para no hacerlo.

La matriz de características

CapacidadBlazor Server (autónomo)Blazor WebAssembly (autónomo)Blazor Web App / United (.NET 11)
Lugar de renderizadoservidornavegadorpor componente (Static, Server, WASM, Auto)
Payload inicial (caché frío)~50-80 KB HTML~1,4 MB WASM + ensamblados (R2R, .NET 11)~50-80 KB HTML, WASM se descarga perezoso
First Contentful Paint (LAN)~80-150 ms~600-900 ms~80-150 ms (Static / Server) ~600-900 ms (WASM-first)
Tiempo hasta interactividad tras FCPdecenas de ms (apertura del WebSocket)cientos de ms (arranque del WASM)depende del modo de render de la página
Requiere WebSocket persistentesí (SignalR)nosolo para componentes Interactive Server
Funciona offlinenosí (con service worker)sí para componentes WebAssembly, no para Server
Acceso directo a base de datos / archivos / secretossí (proceso del servidor)no (sandbox del navegador)sí en componentes Server, no en componentes WASM
Superficie de API .NETruntime de servidor completosubconjunto recortado, seguro para navegadorambas, según el componente
Historia de depuraciónF5 en Visual Studio / Riderdevtools de Chrome + depurador WASM de VSambas
Techo de escala por servidoracotado por circuitos abiertos (~5k por nodo)ilimitado (archivos estáticos + API)acotado solo para las páginas Interactive Server
Soporte Native AOTno (el servidor sigue siendo JIT)parcial vía WASM AOTpor modo de render
Historia de autenticacióncookie + circuitoOIDC / token en el navegadorcookie para SSR/Server, token para WASM
Estado en .NET 11soportado, no es el predeterminado recomendadosoportado, no es el predeterminado recomendadopredeterminado recomendado

La fila que cierra la conversación para la mayoría de las apps nuevas es la última. Las propias plantillas, los ejemplos de la documentación y los tutoriales de Microsoft empiezan con la plantilla Blazor Web App. Elegir solo Server o solo WebAssembly en 2026 es ahora una desviación explícita que necesita justificación.

Cuándo elegir Blazor Server (autónomo)

La plantilla autónoma Blazor Server sigue siendo la opción correcta cuando tienes alguna de estas restricciones:

Un Program.cs mínimo de Blazor Server en .NET 11:

// .NET 11, C# 14, Microsoft.AspNetCore.Components.Server 11.0.x
var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorComponents()
    .AddInteractiveServerComponents();

var app = builder.Build();

app.UseStaticFiles();
app.UseAntiforgery();

app.MapRazorComponents<App>()
    .AddInteractiveServerRenderMode();

app.Run();

Ten en cuenta que AddRazorComponents() más AddInteractiveServerComponents() es la API de .NET 8+. La antigua AddServerSideBlazor() todavía funciona, pero pasa por una capa de compatibilidad y no activa la nueva plomería de modos de render. Usa las APIs nuevas en cualquier proyecto greenfield.

Cuándo elegir Blazor WebAssembly (autónomo)

Recurre a la plantilla autónoma de WebAssembly cuando:

Un Program.cs mínimo de Blazor WebAssembly en .NET 11:

// .NET 11, C# 14, Microsoft.AspNetCore.Components.WebAssembly 11.0.x
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;

var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("#app");
builder.RootComponents.Add<HeadOutlet>("head::after");

builder.Services.AddScoped(sp => new HttpClient
{
    BaseAddress = new Uri(builder.HostEnvironment.BaseAddress)
});

await builder.Build().RunAsync();

En .NET 11 el runtime de WebAssembly tiene multithreading habilitado por defecto en proyectos nuevos cuando activas <WasmEnableThreads>true</WasmEnableThreads> en el .csproj. Eso elimina una de las razones más usadas para descartar Blazor WebAssembly: el trabajo intensivo en CPU ya no bloquea el hilo de UI.

Cuándo elegir Blazor Web App (el modelo United)

Para todo lo demás. La plantilla unificada te da un único proyecto donde:

Esta capacidad de composición es lo que no iguala ninguna otra opción. Dejas de tener una decisión binaria “app Server o app WASM” y pasas a una decisión por página, igual que Next.js te deja mezclar ssr, static y client. Un Program.cs mínimo de Blazor Web App en .NET 11:

// .NET 11, C# 14, Microsoft.AspNetCore.Components.Server 11.0.x +
// Microsoft.AspNetCore.Components.WebAssembly.Server 11.0.x
var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorComponents()
    .AddInteractiveServerComponents()
    .AddInteractiveWebAssemblyComponents();

var app = builder.Build();

app.UseStaticFiles();
app.UseAntiforgery();

app.MapRazorComponents<App>()
    .AddInteractiveServerRenderMode()
    .AddInteractiveWebAssemblyRenderMode()
    .AddAdditionalAssemblies(typeof(BlazorApp.Client._Imports).Assembly);

app.Run();

El proyecto .Client que viene con la plantilla es donde pones los componentes que necesitan correr en WebAssembly. Los componentes solo-servidor quedan en el proyecto host. Los componentes Interactive Auto viven en .Client (porque también deben ser alcanzables desde el lado WebAssembly).

Los datos de cold start y tamaño de bundle

Los números a continuación vienen de un dotnet new blazor, dotnet new blazorserver y dotnet new blazorwasm limpios en el SDK de .NET 11 11.0.100-preview.4.26152.6, publicados con dotnet publish -c Release y servidos por dotnet run. Medidos con Chrome 137 en un MacBook Pro M2, caché frío, con throttling “Fast 3G” en DevTools.

MétricaBlazor ServerBlazor WebAssemblyBlazor Web App (landing Auto)
HTML inicial transferido8 KB4 KB8 KB
WebAssembly + ensamblados transferidos01,42 MB (gzip)1,42 MB (gzip, perezoso)
Tiempo hasta First Contentful Paint320 ms1850 ms340 ms
Tiempo hasta interactividad (botón contador)410 ms2300 ms440 ms (Server) / 2400 ms (handoff a WASM)
Memoria tras la primera navegación7 MB navegador38 MB navegador9 MB y luego 41 MB tras handoff

El Blazor Web App en modo Auto le gana a WebAssembly autónomo en first paint por un factor de cinco porque no espera al bundle. No le gana al Server autónomo porque, una vez que el bundle de WebAssembly termina de cargar, igualmente cuesta memoria. El punto no es que Auto sea el más rápido en una métrica. El punto es que nunca es el más lento.

Para una mirada más profunda a cómo el SDK de .NET 11 recorta el bundle WASM, mira la nueva plantilla Blazor WebWorker de .NET 11, que usa los mismos ajustes del trimmer.

El gotcha que decide por ti

Tres cosas fuerzan la decisión sin importar tu preferencia:

  1. No puedes inyectar un DbContext en un componente WebAssembly. Ni ningún valor de IConfiguration que contenga un secreto. Ni ningún cliente de blob que use una cadena de conexión. El navegador es un entorno hostil por diseño. Si tu componente debe leer la base de datos directamente, tiene que ser Server (o necesitas una API backend a la que llame el componente WASM). La plantilla Blazor Web App lo deja claro fallando rápido: pon @inject ApplicationDbContext Db en un componente .Client y el build falla con un error claro de inyección de dependencias faltante.

  2. No puedes hacer cambios de @rendermode dentro de un límite de modo de render. Una página renderizada como Static Server puede hospedar una isla Interactive Server, y una página Interactive Server puede hospedar islas Interactive WebAssembly, pero no puedes anidar interactividad dentro de interactividad. En la práctica esto significa: elige el modo de render más bajo que sirva para la página y solo escala a nivel de isla.

  3. HTTPS, antiforgery y el estado de autenticación fluyen por cookies por defecto. Los componentes WebAssembly no ven esas cookies en solicitudes cross-origin. Si la parte WebAssembly de un Blazor Web App llama a una API externa, necesitas un flujo de token OIDC encima, no solo la cookie del host. Este es el tropezón más común al migrar una app Blazor Server a la plantilla Web App.

Para el ángulo específico de antiforgery, el comportamiento de TempData en Blazor SSR en .NET 11 y la guía de lógica de validación compartida cubren los patrones prácticos.

Recomendación reformulada

Para un proyecto Blazor nuevo en .NET 11 en 2026, empieza con dotnet new blazor (la plantilla Blazor Web App) y asigna modos de render por página. El costo de poder bajar a @rendermode StaticServer para una página de marketing o subir a @rendermode InteractiveWebAssembly para un componente con capacidad offline es casi nulo comparado con el costo de elegir la plantilla autónoma equivocada y reescribir más tarde. Elige dotnet new blazorserver solo si tienes una prohibición dura de descargas de WebAssembly. Elige dotnet new blazorwasm solo si tu destino de despliegue no tiene runtime .NET, o si estás embebiendo el front-end en MAUI Hybrid o Electron.

Si ya estás en Blazor Server hoy y sopesas una migración, el destino casi siempre es la plantilla Blazor Web App con la mayoría de tus páginas existentes en @rendermode InteractiveServer. Esa es la migración de menor riesgo: el comportamiento queda idéntico para las páginas que se mueven y desbloqueas la opción de añadir componentes Static Server y Auto de forma incremental.

Relacionado

Fuentes

Comments

Sign in with GitHub to comment. Reactions and replies thread back to the comments repo.

< Volver