7 puntos por GN⁺ 2025-05-15 | 1 comentarios | Compartir por WhatsApp
  • Critical CSS es la cantidad mínima de CSS necesaria para renderizar la parte visible al inicio de la página (above the fold); al insertarlo en línea dentro del HTML, mejora Core Web Vitals como el FCP (First Contentful Paint)
  • Se inserta en línea dentro del <head> del HTML para que el navegador pueda renderizar el contenido rápidamente sin esperar a toda la hoja de estilos
  • Ofrece ventajas como mejor percepción de velocidad de carga inicial, aumento del puntaje de Lighthouse y mejoras en SEO y UX
  • El CSS no esencial puede cargarse con un <link> al final del <body> o mediante carga diferida con JavaScript para optimizar aún más el rendimiento
  • Hay que tener en cuenta que el usuario debe ajustar manualmente las rutas de los enlaces CSS y las referencias a recursos

Critical CSS Generator

  • Critical CSS Generator es una herramienta que extrae solo el código CSS mínimo e indispensable de una página web, permitiendo una extracción optimizada según el caso de uso
  • Critical CSS son las reglas CSS mínimas necesarias para dar estilo al área visible inicialmente de la página
  • Este enfoque ayuda a mejorar el rendimiento y Core Web Vitals (como FCP), ya que permite al navegador mostrar de inmediato el contenido principal sin esperar a que carguen todas las hojas de estilo

¿Por qué usarlo?

  • Mayor velocidad percibida en la carga inicial
  • Mejora del puntaje de Lighthouse
  • Mejor SEO y experiencia de usuario

🔧 Cómo aplicarlo

Step 1: Insertar Critical CSS en línea

  • Inserta el Critical CSS dentro de una etiqueta <style> y colócalo en la parte superior del <head> del HTML
  • Debe colocarse antes que cualquier otra hoja de estilos o script
  • Las rutas internas de assets deben ajustarse según sea necesario
    <style>  
      /* Critical CSS for your page */  
      /* ... CSS content ... */  
    </style>  
    

Step 2: Carga diferida del CSS no esencial (método básico)

  • Elimina las etiquetas <link> originales del <head> y colócalas justo antes de </body>
  • De este modo, el renderizado inicial ocurre solo con el Critical CSS, y el CSS no esencial se carga después
    <html>  
      ...  
      <body>  
        ...  
        <link rel="stylesheet" href="/css/vendors.min.css">  
        <link rel="stylesheet" href="/css/style.min.css">  
      </body>  
    </html>  
    

Step 3 (opcional): Carga asíncrona de estilos con JavaScript

  • Después de que termine de cargar la página, usa JavaScript para cargar dinámicamente el CSS no esencial
  • Puede mejorar el rendimiento cuando la velocidad de red es baja
  • Deben eliminarse del <head> todos los <link> de CSS no esencial existentes
    window.addEventListener("DOMContentLoaded", function () {  
      console.log("✅ Page loaded, now loading non-critical stylesheets...");  
      let stylesheets = [  
        // "/css/vendors.min.css",  
        // "/css/style.min.css",  
      ];  
      let loadedCount = 0;  
      function checkAllStylesLoaded() {  
        loadedCount++;  
        if (loadedCount === stylesheets.length) {  
          console.log("✅ All non-critical stylesheets loaded...");  
        }  
      }  
      stylesheets.forEach(function (href) {  
        var link = document.createElement("link");  
        link.rel = "stylesheet";  
        link.href = href;  
        link.onload = checkAllStylesLoaded;  
        link.onerror = () => console.warn(`Failed to load stylesheet: ${href}`);  
        document.head.appendChild(link);  
      });  
    });  
    

1 comentarios

 
GN⁺ 2025-05-15
Comentarios en Hacker News
  • Se vería genial si también soportara diseño responsivo; como es difícil deduplicar estilos críticos responsivos, al final siempre he seguido editando las hojas de estilo a mano. Ya que el tamaño del CSS crítico importa, también estaría bien una opción para hacer down-compile de cosas como variables CSS. Y no recomendaría el consejo de poner la etiqueta <link> del CSS no crítico antes de </body>; el CSS debe recibirse rápido, así que este método retrasa el descubrimiento del CSS y por tanto también su descarga. En cambio, recomiendo un método que combine preload y noscript: <link rel="preload" href="styles.css" as="style" onload="this.rel='stylesheet'"> <noscript><link rel="stylesheet" href="styles.css"></noscript>

    • Me pregunto si este método de usar código JS en ese preload no quedará bloqueado si la CSP no permite unsafe-inline

    • No quiero usar una forma de cargar CSS mediante hacks de JS; al aplicar la hoja de estilos puede recalcularse el layout/estilo de toda la página. El navegador descarga rápidamente la hoja de estilos incluso si está al final de la página.

    • Con solo la combinación de prefetch, hints por headers HTTP y un CDN también se puede lograr un efecto parecido; no hace falta reconstruir continuamente el CSS crítico. Si usas bien un CDN como CF, va rapidísimo.

    • Creo que tienes razón, también planeo agregar una opción así. En lugar de before body, probé una opción DOMContentLoaded, y hasta en teléfonos viejos o redes lentas funciona suficientemente bien para UX y Lighthouse.

    • Totalmente de acuerdo con lo del soporte responsivo.

  • En mi opinión esto se siente como una optimización prematura. Puede tener valor si el CSS es extremadamente complejo o si se cargan muchísimos recursos, pero en la mayoría de los casos es más eficiente escribir CSS, HTML y JS de forma limpia, y este enfoque puede ser innecesario o incluso perjudicial.

    • Es súper útil; como freelancer a menudo trabajo en sitios de WordPress, y muchas veces el CSS/JS termina hecho un desastre después de pasar por varios desarrolladores/agencias. De verdad quiero probar una herramienta así.

    • Cuanto más complejo sea el CSS o cuantos más recursos haya, menor suele ser el beneficio neto de esta optimización. Lo que se busca aquí es optimizar la latencia RTT, y mientras más grande sea el CSS crítico, mayor es el costo de la optimización, así que la ganancia neta disminuye.

    • Hace 12 años habría pagado por una herramienta así. Teníamos cantidades enormes de CSS acumulado durante años, y era difícil saber qué reglas eran críticas.

    • Para muchos sitios definitivamente puede ser una optimización prematura. Pero en sitios sensibles al clic, como noticias o medios, una carga de página “instantánea” es muy importante; si pasa apenas 1 segundo, bajan la retención y los ingresos por publicidad. HuffPost también probó esta optimización hace 10 años.

    • Viendo el estado actual del desarrollo frontend, de verdad se siente excesivo. Herramientas como Lighthouse han hecho que la gente se obsesione con optimizar para números sin sentido; como resultado, solo aumenta la complejidad del build, el usuario real ni lo percibe y desarrollar se vuelve más incómodo. Mientras tanto, todavía veo a menudo sitios llenos de errores básicos de UI/gestión de estado. Es frustrante.

    • La respuesta sí es CSS, HTML y JS limpios, pero a veces te toca heredar proyectos desordenados o usar plantillas, y aun desarrollando yo mismo se me puede enredar el diseño.

    • Para mí, la forma de cargar CSS es algo que hay que considerar sí o sí desde la primera etapa del desarrollo. Tuvimos muchos casos de clientes que se iban porque nuestro sitio sacaba mala puntuación en page speed tests. Como el rendimiento afecta al SEO, es muy importante. Rediseñé personalmente la optimización de páginas para sacar 100 puntos en Google Lighthouse; hay que planear desde el inicio incluso el orden y la forma de cargar CSS/JS para reducir retrabajo después. Nosotros dividimos el CSS por encima y por debajo del fold y lo incluimos inline donde correspondía; el JS por debajo del fold ni siquiera se evalúa hasta que se hace scroll. Aplicamos todo lo que sugería Lighthouse. El sistema anterior cargaba en todas las páginas todo el CSS del sitio (3~4MB), y el JS era todavía peor; fue por no haber diseñado la optimización desde el principio. Seguimos usando ese sistema, así que no puedo decir el nombre, pero internamente sigue siendo un problema. Si el objetivo es el rendimiento, no creo que exista el concepto de optimización prematura: hay que considerar todo desde el inicio. Como resultado, obtenemos 100 de rendimiento para todos los clientes, incluyendo móviles, y tenemos ventaja frente a la competencia. Probé esta herramienta en mi sitio y ya tenía todo tan optimizado que no hubo efecto.

  • En mi página hecha con Astro, el HTML es 27.52KB (6.1KB comprimido), el JS es menos de 10KB y el CSS crítico 57KB (7KB comprimido). Sitios parecidos van de 100KB a 1MB. Si construyes limpio, con resource hints basta para que sea rápido incluso sin inline css/js. Con una combinación de nginx+HTTP/2+edge cache se puede lograr 100/100 de rendimiento sin CSS crítico ni JS inline. No sé si tenga sentido agregar 7KB extra por página; en implementación, SPA/edge caching es mucho más ecológico y rápido. No hay necesidad de enviar HTML exageradamente pesado como con Elementor, y la batería del móvil es limitada como para enviar datos innecesarios.

    • Es un buen truco, pero en una situación donde CDN y HTTP/2 ya son comunes, este tipo de optimización al final solo desperdicia ancho de banda. Apenas mejora un poco los números de benchmark, y en la práctica solo acelera unos 10~20ms.

    • Incluir CSS crítico en todas las páginas no siempre es la respuesta. Usarlo selectivamente solo en la primera visita (sin caché) o en la página inicial de una sesión también puede evitar data bloat innecesario.

  • Busqué una herramienta para extraer CSS crítico por pedido de un cliente, pero como no encontré lo que quería, terminé compartiendo una solución propia hecha con Puppeteer. Se puede indicar cuánto esperar después de cargar la página. También probé servicios de pago, pero no me gustaron y pedí reembolso. Agradezco el feedback; por ahora lo abrí gratis.

    • Me da curiosidad si el problema era con herramientas existentes como el paquete penthouse.

    • Si ingresas un sitio sin CSS, aparece un error.

    • ¿El código está publicado? También me gustaría usarlo como plugin de Vite/Astro.

    • Quisiera preguntar si es una versión con UI de penthouse; muchos valores de configuración se parecen bastante.

  • Este método más bien produce el efecto contrario. Genera un FOUC (parpadeo de contenido sin estilos) muy consistente; si el layout cambia a mitad de la interacción, un usuario que ya estaba haciendo clic puede sufrir una molestia importante. No es solo un problema visual, sino de usabilidad real.

    • Yo también ajusté algunos estilos después de aplicar este método, pero al final sí pude optimizar hasta lograr CLS (cumulative layout shift) 0. Cuando tienes poco presupuesto y usas plantillas con muchas librerías, puede ser muy útil.

    • ¿No se supone que el objetivo original es evitar el FOUC sin bloquear el network request del CSS?

  • Este enfoque tiene más sentido bajo la suposición de que en la primera vista de la página no hay absolutamente nada de caché CSS. En la práctica, hay trade-offs entre varios factores: proporción de usuarios nuevos/recurrentes, configuración de caché CSS, CDN, 103 early hints, CSS crítico/initial congestion window, etc.

    • Sí, está pensado para la primera entrada, y más que un método realmente recomendable es un trade-off. Lo mejor es escribir tú mismo todo el código y los estilos, y reducir el uso de librerías.
  • Al medir rendimiento en localhost, la influencia del CSS era casi nula. Incluso eliminando por completo el CSS, la mejora era menor a 7ms, y eso ya entra dentro del margen de error de la medición.

    • Las optimizaciones de rendimiento para latencia cliente-servidor obviamente no tienen sentido en entornos de baja latencia como localhost. No digo que esta optimización sea obligatoria, pero probar en localhost no es una buena referencia.
  • Al usar esta herramienta en mi sitio, se extrajo al CSS incluso contenido de debugging que no era estrictamente necesario; por ejemplo, body::after para un overlay de cuadrícula del sitio también quedó incluido tal cual (ni me acordaba de eso hasta que lo descubrí ahora).

  • Prefiero escribir HTML que comunique bien el significado incluso sin CSS. Así puedes evitar desde antes que la estructura del documento se vuelva demasiado compleja.

    • Pero eso no aplica a todos los sitios; por ejemplo, hay muchas UI donde la lectura de izquierda a derecha y de arriba abajo no es lo predeterminado.
  • La idea en sí me pareció fresca y la probé en mi sitio personal, pero en la librería penthouse ocurrió un error de omisión de CSS: {"error":true,"name":"Error","message":"css should not be empty" ...}

    • También voy a revisar este caso, gracias.