Eliminar el CSS que bloquea el renderizado en Next.js para mejorar los Core Web Vitals
Elimina el CSS que bloquea el renderizado en Next.js para unos Core Web Vitals más rápidos

Eliminar el CSS que bloquea el renderizado en Next.js
El CSS bloquea el renderizado. El navegador no pintará un solo píxel hasta que haya descargado y analizado cada hoja de estilo en el <head>. En una aplicación Next.js, esto significa dos archivos CSS externos de forma predeterminada: una hoja de estilo global y una hoja de estilo específica de la página. En una conexión 3G rápida, la descarga de esos dos archivos te cuesta 600ms antes de que el navegador comience a renderizar. Esos son 600ms añadidos directamente a tu First Contentful Paint y Largest Contentful Paint.
Revisado por última vez por Arjen Karel en marzo de 2026
Table of Contents!
- Eliminar el CSS que bloquea el renderizado en Next.js
- App Router frente a Pages Router
- Opción 1: Generar Critical CSS (Pages Router)
- Opción 2: Poner todo el CSS en línea en el head (Pages Router)
- Opción 3: Styled Components (Pages Router)
- Opción 4: CSS en línea con inlineCss (App Router, Next.js 15+)
- Una nota sobre CSS Modules y Tailwind CSS
- ¿Qué opción debería usar?
De media, en todos mis clientes y todos los dispositivos, mido unos 200ms de retraso causado por el CSS que bloquea el renderizado. Según el Web Almanac de 2025, el 85% de las páginas móviles aún fallan en la auditoría de recursos que bloquean el renderizado. La página mediana carga 8 archivos CSS con un total de 79 KB. En conexiones móviles lentas, el retraso del renderizado puede representar el 69% del tiempo total de LCP. Es hora de arreglar esto.

App Router frente a Pages Router
La solución depende de qué enrutador de Next.js utilices. El Pages Router (usando _document.tsx) y el App Router (usando app/layout.tsx) manejan la entrega de CSS de manera diferente. La integración de critical CSS a través de critters no funciona con el App Router porque el streaming es incompatible con la forma en que critters procesa el HTML. Si estás en el App Router, pasa a la Opción 4.
El App Router es el predeterminado desde Next.js 13.4. Pero muchas aplicaciones en producción todavía ejecutan el Pages Router, y las tres primeras opciones a continuación siguen siendo válidas para ellas.
Opción 1: Generar Critical CSS (Pages Router)
La opción más rápida es generar critical CSS. El critical CSS es una colección de reglas CSS necesarias para renderizar la parte visible de la página. Esas reglas se colocan en línea en el <head>. Luego, en paralelo, se descargan los archivos CSS originales mientras el navegador continúa renderizando. Una vez que se descargan los archivos CSS originales, se inyectan en la página.
El critical CSS está disponible en Next.js como una característica experimental. Añade experimental: { optimizeCss: true } a tu next.config.js. Next.js incluye la biblioteca critters internamente, por lo que no es necesario instalarla por separado. Ten en cuenta que el paquete original de critters está obsoleto (reemplazado por el fork de beasties), pero Next.js aún no ha hecho el cambio.
const nextConfig = {
reactStrictMode: true,
experimental: { optimizeCss: true }
}
Esta opción solo funciona con el Pages Router. No soporta el App Router porque critters necesita el HTML renderizado completo, lo cual es incompatible con el streaming.
Opción 2: Poner todo el CSS en línea en el head (Pages Router)
Si no quieres habilitar características experimentales en tu aplicación Next.js, podrías considerar poner tu CSS en línea manualmente. Crea una sección head personalizada y haz referencia a ella en tu _document.tsx.
La desventaja es que el CSS en línea será más grande que con el primer método porque estás poniendo todo en línea, no solo las reglas críticas. Sin embargo, si mantienes tus hojas de estilo limpias y ligeras, esto mejorará significativamente los Core Web Vitals de tu aplicación Next.js.
import { Html, Head, Main, NextScript } from "next/document";
import { readFileSync } from "fs";
import { join } from "path";
class InlineStylesHead extends Head {
getCssLinks: Head["getCssLinks"] = ({ allFiles }) => {
const { assetPrefix } = this.context;
if (!allFiles || allFiles.length === 0) return null;
return allFiles
.filter((file: any) => /\.css$/.test(file))
.map((file: any) => (
<style
key={file}
nonce={this.props.nonce}
data-href={`${assetPrefix}/_next/${file}`}
dangerouslySetInnerHTML={{
__html: readFileSync(join(process.cwd(), ".next", file), "utf-8"),
}}
/>
));
};
}
export default function Document() {
return (
<Html>
<InlineStylesHead />
<body>
<Main />
<NextScript />
</body>
</Html>
);
}
Opción 3: Styled Components (Pages Router)
Styled Components es una herramienta CSS-in-JS que te permite escribir CSS en archivos JavaScript. Puedes acotar los nombres de las clases, eliminar el CSS no utilizado automáticamente y gestionar los estilos junto a tus componentes. Para los Core Web Vitals, significa que solo se inyectan los estilos necesarios en esa página.
Añade compiler: { styledComponents: true } a tu next.config.js, instala styled-components (yarn add styled-components y yarn add -D @types/styled-components), luego actualiza _document.js para soportar la renderización del lado del servidor para styled components.
const nextConfig = {
reactStrictMode: true,
compiler: {
styledComponents: true,
}
}
import Document, { DocumentContext } from "next/document";
import { ServerStyleSheet } from "styled-components";
export default class MyDocument extends Document {
static async getInitialProps(ctx: DocumentContext) {
const sheet = new ServerStyleSheet();
const originalRenderPage = ctx.renderPage;
try {
ctx.renderPage = () =>
originalRenderPage({
enhanceApp: (App) => (props) =>
sheet.collectStyles(<App {...props} />),
});
const initialProps = await Document.getInitialProps(ctx);
return {
...initialProps,
styles: (
<>
{initialProps.styles}
{sheet.getStyleElement()}
</>
),
};
} finally {
sheet.seal();
}
}
}
Si usas el App Router con styled-components, necesitas una configuración diferente. Crea un componente cliente de registro de estilos utilizando useServerInsertedHTML y envuelve tu root layout con él. Los styled components solo funcionan en los Client Components en el App Router. Consulta la guía de CSS-in-JS de Next.js para ver el patrón completo.
Opción 4: CSS en línea con inlineCss (App Router, Next.js 15+)
Para el App Router, Next.js 15 introdujo experimental.inlineCss. Esto reemplaza todas las etiquetas de hoja de estilo <link> con etiquetas <style> en línea, eliminando por completo la cascada que bloquea el renderizado.
const nextConfig = {
experimental: {
inlineCss: true,
}
}
Esto todavía es experimental y el equipo de Next.js aún no lo recomienda para producción. Pone en línea todo el CSS (no solo el critical CSS), lo que aumenta el tamaño del HTML. Para los sitios que utilizan Tailwind CSS, este compromiso funciona bien porque Tailwind genera paquetes CSS atómicos pequeños. Para los sitios con hojas de estilo grandes, la sobrecarga de HTML puede perjudicar al Time to First Byte.
Una nota sobre CSS Modules y Tailwind CSS
CSS Modules y Tailwind CSS son los dos enfoques de estilo más populares en Next.js hoy en día. Ambos compilan en archivos CSS estándar en el momento de la construcción y se sirven como etiquetas <link>. Eso significa que bloquean el renderizado de forma predeterminada.
Tailwind tiene una ventaja: debido a que purga las clases no utilizadas, el resultado suele ser muy pequeño (a menudo menos de 10 KB comprimidos en gzip). El impacto de bloqueo de renderizado de un archivo de 10 KB es mínimo. Los CSS Modules pueden hacerse más grandes si no tienes cuidado con los estilos no utilizados.
De cualquier manera, se aplican todas las opciones anteriores. Si deseas eliminar por completo el CSS que bloquea el renderizado, combina tu enfoque de estilo preferido con optimizeCss (Pages Router) o inlineCss (App Router).
¿Qué opción debería usar?
Depende de tu enrutador y de tu estrategia CSS:
- App Router + Tailwind: Usa
inlineCss. Los paquetes CSS pequeños hacen que la integración en línea sea práctica. - App Router + CSS grande: Espera a que
inlineCssse estabilice, o usa una configuración personalizada de beasties. - Pages Router: Usa
optimizeCss(Opción 1). Es la solución más sencilla y solo pone en línea lo que es crítico. - Pages Router + CSS-in-JS: Usa styled-components o Emotion con los patrones de renderización del lado del servidor (SSR) mostrados anteriormente.
En los sitios Next.js monitorizados por CoreDash, aquellos que utilizan critical CSS en línea muestran una mejora de la mediana de FCP de 400ms en comparación con la entrega de CSS predeterminada. Esa es la diferencia entre un buen y un mediocre resultado de FCP.
Sea cual sea la opción que elijas, verifica los resultados con Real User Monitoring. Las puntuaciones de laboratorio te dicen lo que podría pasar. Los datos de campo te dicen lo que realmente sucedió.
Para obtener más información sobre cómo interactúan el CSS y JavaScript con el canal de renderizado, consulta la guía completa para solucionar los recursos que bloquean el renderizado. Si estás optimizando una aplicación Next.js, consulta también las guías sobre cómo arreglar scripts de terceros y cómo medir los Core Web Vitals en Next.js. Para una visión más amplia de la estrategia de carga, la guía de priorización de recursos cubre cómo los navegadores deciden qué obtener primero.
Search Console flagged your site?
When Google flags your Core Web Vitals you need a clear diagnosis fast. I deliver a prioritized fix list within 48 hours.
Request Urgent Audit
