Contents
Introducción: qué es CSS crítico y por qué extraerlo
El CSS crítico (critical CSS) son las reglas CSS necesarias para renderizar el above-the-fold de una página —es decir, lo que el usuario ve inmediatamente sin hacer scroll—. Inyectar ese CSS inline en el head reduce el render-blocking y mejora métricas como First Contentful Paint (FCP) y Largest Contentful Paint (LCP), algo especialmente relevante en WordPress donde se cargan hojas de estilo grandes y frameworks.
Resumen de la estrategia
- Generar CSS crítico por plantilla/URL (puede ser en build time o de forma programada en el servidor).
- Almacenar el CSS crítico en archivos o en la base de datos (transients/option).
- Detectar la plantilla/page en PHP y inyectar inline solo el CSS crítico correspondiente.
- Cargar la hoja de estilos completa de forma no bloqueante (preload onload o carga asíncrona) y ofrecer fallback para navegadores sin soporte.
- Mecanismos de regenerado y cache para mantener actualizada la versión crítica tras cambios en estilos o plantilla.
Requisitos y herramientas recomendadas
Para generar CSS crítico existen herramientas maduras que funcionan con Puppeteer/Headless Chrome y analizan el HTML renderizado:
- critical (npm) — fácil de usar en build scripts.
- penthouse — más control sobre viewport y reglas.
- Scripts personalizados con Puppeteer cuando se necesita interactividad previa (ej. clases añadidas por JS).
Recomendación: no generar CSS crítico en cada petición. Hacerlo en un paso de build o en tareas programadas (cron / WP Cron) y servir el resultado desde archivos en el servidor para rendimiento y seguridad.
Implementación A — Pre-generación (build time) y carga condicional en PHP
Flujo: en el pipeline (Gulp, npm script, CI) generas archivos como critical-home.css, critical-single.css, etc. Luego en WordPress, según la plantilla, lees y añades el contenido inline en el head y cargas la hoja completa diferida.
Ejemplo: generación con la herramienta critical (CLI)
# Generar critical CSS para la home y guardarlo en un archivo npx critical https://mi-dominio.test/ --width=1300 --height=900 --minify --extract --inline=false --target=critical-home.css # Para una URL de ejemplo de artículo npx critical https://mi-dominio.test/mi-articulo/ --width=1300 --height=900 --minify --inline=false --target=critical-single.css
Ejemplo: código PHP para inyectar el CSS crítico y cargar el CSS completo sin bloqueo
n . css . nn } } } // Encolar la hoja completa de forma no bloqueante add_action(wp_enqueue_scripts, mi_encolar_css_no_bloqueante, 20) function mi_encolar_css_no_bloqueante() { // Ruta y handle de la hoja completa handle = theme-styles src = get_stylesheet_uri() // o tu ruta a CSS compilado // Encolamos normalmente (para que WP la registre) pero la imprimiremos como preload onload wp_register_style(handle, src, array(), filemtime( get_stylesheet_directory() . /style.css )) wp_enqueue_style(handle) // Evitamos que WP imprima el link automáticamente (no siempre necesario, depende del flujo). // En muchos casos se puede dejar y añadir otro link preload manual en head. A continuación, ejemplo manual: } // Imprimir link preload onload justo en head, y fallback
Implementación B — Generación dinámica en servidor (programada) y entrega condicional
En sitios con muchas URLs dinámicas (woocommerce, sites grandes) puedes generar critical CSS por ruta con un proceso en servidor. Recomendación: hacerlo en background (cron real o WP Cron) y no en la petición del usuario. A continuación un patrón seguro y controlado.
Arquitectura recomendada
- Cola o lista de URLs que necesitan regenerar critical CSS (por cambios de estilo o contenido).
- Un proceso cron que consume la lista y llama a un script Node (penthouse/critical) para generar el CSS y guardar el archivo.
- PHP que sirve el archivo crítico ya generado cuando se solicita la URL correspondiente.
Ejemplo: comando Node desde PHP (a ejecutar por WP Cron evitar shell_exec desde peticiones públicas)
/dev/null 2>1 shell_exec( cmd_bg ) } ?>
Ejemplo: script Node con penthouse (generate-critical.js)
// generate-critical.js // Uso: node generate-critical.js https://mi-dominio.test/mi-articulo/ /var/www/wp-content/critical-css/critical-mi-articulo.css const fs = require(fs) const penthouse = require(penthouse) const argv = process.argv const url = argv[2] const out = argv[3] if (!url !out) { console.error(Usage: node generate-critical.js
Cache, versión y invalidación
Mantener sincronización entre CSS principal y crítico es clave. Estrategias:
- Versiona las hojas completas con filemtime() y añade el mismo timestamp a la lista de generación del critical.
- Cuando cambie el CSS (deploy), dispara la regeneración de todos los critical CSS relevantes desde el build o desde un hook de deploy.
- Usa transients o un pequeño tabla personalizada para llevar el control de estado de generación y evitar colisiones.
Consideraciones sobre fuentes, imágenes y reglas dinámicas
- Las font-face y cargas de fuentes: incluir solo lo necesario en el critical (por ejemplo font-display: swap) y hacer preloads de fuentes críticas. Alternativamente, no inyectes @font-face completos si vienen de Google Fonts mejor preload la fuente y dejar la carga del CSS de fuentes diferida.
- Evita incluir reglas complejas o grandes en critical prioriza sólo lo que está en el viewport inicial.
- Si tu sitio aplica clases dinámicamente vía JS (por ejemplo menús que se abren), genera critical con esas interacciones simuladas en Puppeteer si esas clases afectan el above-the-fold.
Validación y pruebas
Para comprobar resultados:
- Usa Lighthouse (Chrome DevTools) antes y después para ver mejoras en FCP/LCP.
- Prueba en conexiones lentas y dispositivos móviles reales para asegurarte de que no rompes estilos por eliminación excesiva.
- Revisa el tamaño del ltstyle id=critical-cssgt y procura que sea razonable (normalmente unos pocos KB para la home). Si crece mucho, reevalúa la selección de reglas o el viewport objetivo.
Buenas prácticas y errores comunes
- No generar critical CSS en cada petición. Solo en build o en procesos programados.
- Sanea y controla los comandos que lanzas desde PHP (escapeshellcmd, permisos limitados, ejecución en background).
- Ofrece fallback: ltnoscriptgtltlink rel=stylesheetgtlt/noscriptgt para navegadores sin JS o sin soporte onload.
- Mantén una estrategia de cache-busting coherente entre archivos completos y críticos.
- Documenta qué plantillas tienen archivos críticos y cómo regenerarlos (para el equipo).
Ejemplo completo — resumen de flujo en PHP
A modo de síntesis, este es el flujo mínimo que ofrece seguridad y rendimiento:
- En build/cron generas archivos en wp-content/critical-css/ (uno por plantilla o slug).
- En wp_head, con prioridad alta, lees y escribes el contenido del archivo crítico en una etiqueta ltstyle id=critical-cssgt.
- En wp_head también imprimimos un ltlink rel=preload as=style onload=this.rel=quotstylesheetquotgt al CSS principal y un ltnoscriptgt con el link de hoja de estilos.
- Versionamos con filemtime y regeneramos los critical CSS tras cambios en compilación o deploy.
Piezas de código adicionales (pequeñas utilidades)
Utilidad para obtener slug seguro para archivo a partir de URL/ID:
mi-articulo slug = trim( path, / ) if ( ! slug ) { slug = home } // limpiar caracteres no permitidos slug = preg_replace( /[^a-z0-9-_]/, -, strtolower( slug ) ) return slug } ?>
Conclusión
Extraer e inyectar CSS crítico de forma condicional en WordPress es una técnica de optimización poderosa que reduce el tiempo necesario para que el usuario vea contenido útil. La clave es generar el CSS crítico fuera del ciclo de petición (build o cron), almacenarlo ordenadamente por plantilla/URL y, desde PHP, inyectarlo sólo cuando corresponda, mientras se carga la hoja completa de forma no bloqueante. Aplicando las prácticas de seguridad y cache indicadas obtendrás mejoras sustanciales en las métricas de carga sin comprometer la estabilidad visual.
|
Acepto donaciones de BAT's mediante el navegador Brave 🙂 |