Files
roi-theme/Public/CriticalCSS/Infrastructure/Services/CriticalCSSInjector.php
FrankZamora e01605ec37 feat(critical-css): implementar TIPO 4 y TIPO 5 - CSS Below-the-fold y Lazy Loading
## TIPO 4: CSS Below-the-fold (Critical Variables + Responsive)
- Inyecta variables CSS críticas inline en wp_head P:-1
- Inyecta media queries críticas inline en wp_head P:2 (corregido de P:1)
- Auto-regeneración cuando archivos fuente cambian (filemtime check)
- Cache en Assets/CriticalCSS/ para evitar lecturas repetidas
- Comando WP-CLI: wp roi-theme generate-critical-css

Archivos TIPO 4:
- Public/CriticalCSS/Domain/Contracts/ - Interfaces (DIP)
- Public/CriticalCSS/Application/UseCases/GetCriticalCSSUseCase.php
- Public/CriticalCSS/Infrastructure/Cache/CriticalCSSFileCache.php
- Public/CriticalCSS/Infrastructure/Services/CriticalCSSExtractor.php
- Public/CriticalCSS/Infrastructure/Services/CriticalCSSInjector.php
- bin/generate-critical-css.php

## TIPO 5: CSS No Crítico (Lazy Loading)
- Animaciones CSS: carga 2s después de page load via requestIdleCallback
- Print CSS: carga solo al imprimir via beforeprint event
- Fallback <noscript> para usuarios sin JavaScript
- Safari fallback: setTimeout cuando requestIdleCallback no disponible

Archivos TIPO 5:
- Assets/Js/lazy-css-loader.js
- Public/LazyCSSLoader/Infrastructure/Contracts/LazyCSSRegistrarInterface.php
- Public/LazyCSSLoader/Infrastructure/Services/LazyCSSRegistrar.php

## Fix: Colisión de prioridades wp_head
Antes: TIPO 1 (P:1), TIPO 4 responsive (P:1), TIPO 3 (P:2) - CONFLICTO
Después: TIPO 1 (P:1), TIPO 4 responsive (P:2), TIPO 3 (P:3) - OK

Nuevo orden de prioridades:
P:-1 roi-critical-variables (TIPO 4)
P:0  roi-critical-bootstrap (TIPO 2)
P:1  roi-critical-css (TIPO 1)
P:2  roi-critical-responsive (TIPO 4)
P:3  roi-custom-critical-css (TIPO 3)
P:5  roi-theme-layout-css (ThemeSettings)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-01 23:06:12 -06:00

87 lines
2.2 KiB
PHP

<?php
declare(strict_types=1);
namespace ROITheme\Public\CriticalCSS\Infrastructure\Services;
use ROITheme\Public\CriticalCSS\Domain\Contracts\CriticalCSSCacheInterface;
/**
* Inyecta CSS critico en wp_head
*
* Prioridades:
* - P:-1 Variables CSS (antes de todo)
* - P:1 Responsive critico (despues de Bootstrap critico)
*
* @package ROITheme\Public\CriticalCSS\Infrastructure\Services
*/
final class CriticalCSSInjector
{
public function __construct(
private readonly CriticalCSSCacheInterface $cache
) {}
/**
* Registra hooks de WordPress
*/
public function register(): void
{
// Variables CSS: P:-1 (antes de CriticalBootstrapService P:0)
add_action('wp_head', [$this, 'injectVariables'], -1);
// Responsive critico: P:2 (despues de CriticalCSSService P:1)
// NOTA: Cambiado de P:1 a P:2 para evitar colision con roi-critical-css
add_action('wp_head', [$this, 'injectResponsive'], 2);
// Deshabilitar enqueue de archivos que ahora son inline
add_action('wp_enqueue_scripts', [$this, 'dequeueInlinedCSS'], 999);
}
/**
* Inyecta variables CSS criticas
*/
public function injectVariables(): void
{
$css = $this->cache->get('variables');
if (empty($css)) {
return;
}
printf(
'<!-- TIPO 4: Variables CSS criticas -->' . "\n" .
'<style id="roi-critical-variables">%s</style>' . "\n",
$css
);
}
/**
* Inyecta media queries criticas
*/
public function injectResponsive(): void
{
$css = $this->cache->get('responsive');
if (empty($css)) {
return;
}
printf(
'<!-- TIPO 4: Responsive critico -->' . "\n" .
'<style id="roi-critical-responsive">%s</style>' . "\n",
$css
);
}
/**
* Deshabilita enqueue de archivos que ahora estan inline
*/
public function dequeueInlinedCSS(): void
{
// Variables ya inline - no cargar archivo externo
if ($this->cache->has('variables')) {
wp_dequeue_style('roi-variables');
wp_deregister_style('roi-variables');
}
}
}