feat(pagespeed): implementar campo is_critical para CSS crítico dinámico (Phase 4.2)

Implementación completa del sistema de Critical CSS dinámico según plan 13.01:

Domain Layer:
- Crear CriticalCSSCollectorInterface para DIP compliance

Infrastructure Layer:
- Implementar CriticalCSSCollector (singleton via DIContainer)
- Crear CriticalCSSHooksRegistrar para inyección en wp_head
- Actualizar DIContainer con getCriticalCSSCollector()

Schemas:
- Agregar campo is_critical a navbar, top-notification-bar, hero
- Sincronizar con BD (18+39+31 campos)

Renderers (navbar, top-notification-bar, hero):
- Inyectar CriticalCSSCollectorInterface via constructor
- Lógica condicional: si is_critical=true → CSS a <head>

Admin (FormBuilders + FieldMappers):
- Toggle "CSS Crítico" en sección visibility
- Mapeo AJAX para persistencia

Beneficios:
- LCP optimizado: CSS crítico inline en <head>
- Above-the-fold rendering sin FOUC
- Componentes configurables desde admin panel

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
FrankZamora
2025-11-29 09:29:45 -06:00
parent 6d03076032
commit 4f25297f14
17 changed files with 340 additions and 15 deletions

View File

@@ -114,6 +114,28 @@ function roi_get_navbar_setting(string $group, string $attribute, $default = nul
return $value;
}
// =============================================================================
// CRITICAL CSS COLLECTOR SINGLETON
// =============================================================================
/**
* Obtiene la instancia singleton del CriticalCSSCollector
*
* Patrón Singleton implementado via función para mantener una única instancia
* que será compartida por todos los Renderers y el HooksRegistrar
*
* @return \ROITheme\Shared\Domain\Contracts\CriticalCSSCollectorInterface
*/
function roi_get_critical_css_collector(): \ROITheme\Shared\Domain\Contracts\CriticalCSSCollectorInterface {
static $collector = null;
if ($collector === null) {
$collector = new \ROITheme\Shared\Infrastructure\Services\CriticalCSSCollector();
}
return $collector;
}
// =============================================================================
// HELPER FUNCTION: roi_render_component()
// =============================================================================
@@ -186,22 +208,27 @@ function roi_render_component(string $componentName): string {
// Crear instancia del CSSGeneratorService (reutilizable para todos los renderers que lo necesiten)
$cssGenerator = new \ROITheme\Shared\Infrastructure\Services\CSSGeneratorService();
// Obtener instancia singleton del CriticalCSSCollector
$criticalCollector = roi_get_critical_css_collector();
switch ($componentName) {
// Componentes nuevos (namespace PascalCase correcto)
// Componentes con soporte de CSS Crítico (above-the-fold)
case 'top-notification-bar':
$renderer = new \ROITheme\Public\TopNotificationBar\Infrastructure\Ui\TopNotificationBarRenderer($cssGenerator);
$renderer = new \ROITheme\Public\TopNotificationBar\Infrastructure\Ui\TopNotificationBarRenderer($cssGenerator, $criticalCollector);
break;
case 'navbar':
$renderer = new \ROITheme\Public\Navbar\Infrastructure\Ui\NavbarRenderer($cssGenerator);
break;
case 'cta-lets-talk':
$renderer = new \ROITheme\Public\CtaLetsTalk\Infrastructure\Ui\CtaLetsTalkRenderer($cssGenerator);
$renderer = new \ROITheme\Public\Navbar\Infrastructure\Ui\NavbarRenderer($cssGenerator, $criticalCollector);
break;
case 'hero':
error_log("ROI Theme DEBUG: Creating HeroRenderer");
$renderer = new \ROITheme\Public\Hero\Infrastructure\Ui\HeroRenderer($cssGenerator);
$renderer = new \ROITheme\Public\Hero\Infrastructure\Ui\HeroRenderer($cssGenerator, $criticalCollector);
error_log("ROI Theme DEBUG: HeroRenderer created successfully");
break;
// Componentes sin soporte de CSS Crítico (below-the-fold)
case 'cta-lets-talk':
$renderer = new \ROITheme\Public\CtaLetsTalk\Infrastructure\Ui\CtaLetsTalkRenderer($cssGenerator);
break;
case 'hero-section':
$renderer = new \ROITheme\Public\HeroSection\Infrastructure\Ui\HeroSectionRenderer();
break;
@@ -250,9 +277,21 @@ function roi_render_component(string $componentName): string {
}
// =============================================================================
// ESTILOS BASE PARA TOP NOTIFICATION BAR
// REGISTRO DE CRITICAL CSS HOOKS
// =============================================================================
/**
* Registra el hook para inyectar CSS crítico en <head>
*
* IMPORTANTE: El HooksRegistrar usa la misma instancia singleton del collector
* que usan los Renderers, garantizando que el CSS recolectado se inyecte
* correctamente en wp_head con prioridad 1 (muy temprano).
*/
add_action('after_setup_theme', function() {
$criticalCollector = roi_get_critical_css_collector();
$hooksRegistrar = new \ROITheme\Shared\Infrastructure\Wordpress\CriticalCSSHooksRegistrar($criticalCollector);
$hooksRegistrar->register();
});
// =============================================================================
// NOTA: Los estilos de TOC y CTA Box Sidebar se generan dinámicamente