From d8fa5cb60949942f9f918de0cecb36858177aa11 Mon Sep 17 00:00:00 2001 From: FrankZamora Date: Tue, 2 Dec 2025 10:01:12 -0600 Subject: [PATCH] fix(fonts): eliminar CLS en navbar causado por font swap MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Agregar font preload en P:-2 para fuentes Poppins críticas (400, 600, 700) - Cambiar font-display: optional → swap para garantizar carga de fuente - Ajustar size-adjust: 106% → 100.6% para minimizar salto visual - Nuevo orden prioridades: P:-2 → P:-1 → P:0 → P:1 → P:2 → P:3 → P:5 Archivos: - CriticalCSSInjector.php: nuevo método preloadFonts() - css-global-fonts.css: @font-face optimizado 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- Assets/Css/css-global-fonts.css | 21 ++++++----- .../Services/CriticalCSSInjector.php | 36 +++++++++++++++++-- 2 files changed, 47 insertions(+), 10 deletions(-) diff --git a/Assets/Css/css-global-fonts.css b/Assets/Css/css-global-fonts.css index 25afaac6..24a4f718 100644 --- a/Assets/Css/css-global-fonts.css +++ b/Assets/Css/css-global-fonts.css @@ -58,16 +58,21 @@ Formato: WOFF2 (mejor compresión) Fase 4.3 PageSpeed: Fallback con size-adjust para reducir CLS - - size-adjust: 106% ajusta métricas del fallback para coincidir con Poppins - - Reduce layout shift cuando las fuentes se intercambian + - size-adjust: 100.6% ajustado para coincidir mejor con Poppins + - font-display: swap + preload = carga rapida sin salto visual + - Preload en CriticalCSSInjector P:-2 acelera descarga de fuentes + + NOTA: El valor 100.6% fue calibrado empiricamente. + - 106% causaba un salto visual notable (navbar se "achicaba") + - 100.6% minimiza el CLS manteniendo legibilidad del fallback ============================================ */ -/* Fallback font con métricas ajustadas para Poppins */ +/* Fallback font con metricas ajustadas para Poppins */ @font-face { font-family: 'Poppins Fallback'; src: local('Arial'), local('Helvetica Neue'), local('Helvetica'), local('sans-serif'); - size-adjust: 106%; + size-adjust: 100.6%; ascent-override: 105%; descent-override: 35%; line-gap-override: 10%; @@ -78,7 +83,7 @@ src: url('../Fonts/poppins-v24-latin-regular.woff2') format('woff2'); font-weight: 400; font-style: normal; - font-display: optional; + font-display: swap; } @font-face { @@ -86,7 +91,7 @@ src: url('../Fonts/poppins-v24-latin-500.woff2') format('woff2'); font-weight: 500; font-style: normal; - font-display: optional; + font-display: swap; } @font-face { @@ -94,7 +99,7 @@ src: url('../Fonts/poppins-v24-latin-600.woff2') format('woff2'); font-weight: 600; font-style: normal; - font-display: optional; + font-display: swap; } @font-face { @@ -102,7 +107,7 @@ src: url('../Fonts/poppins-v24-latin-700.woff2') format('woff2'); font-weight: 700; font-style: normal; - font-display: optional; + font-display: swap; } /* ============================================ diff --git a/Public/CriticalCSS/Infrastructure/Services/CriticalCSSInjector.php b/Public/CriticalCSS/Infrastructure/Services/CriticalCSSInjector.php index 72c19cca..d12a2eb4 100644 --- a/Public/CriticalCSS/Infrastructure/Services/CriticalCSSInjector.php +++ b/Public/CriticalCSS/Infrastructure/Services/CriticalCSSInjector.php @@ -9,8 +9,9 @@ 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) + * - P:-2 Font preload (antes de variables) + * - P:-1 Variables CSS (antes de Bootstrap) + * - P:2 Responsive critico (despues de Bootstrap critico) * * @package ROITheme\Public\CriticalCSS\Infrastructure\Services */ @@ -20,11 +21,23 @@ final class CriticalCSSInjector private readonly CriticalCSSCacheInterface $cache ) {} + /** + * Fuentes criticas para preload (pesos usados en navbar above-the-fold) + */ + private const CRITICAL_FONTS = [ + '/Assets/Fonts/poppins-v24-latin-regular.woff2', // 400 - body text + '/Assets/Fonts/poppins-v24-latin-600.woff2', // 600 - navbar brand + '/Assets/Fonts/poppins-v24-latin-700.woff2', // 700 - headings + ]; + /** * Registra hooks de WordPress */ public function register(): void { + // Font preload: P:-2 (antes de todo, incluso variables) + add_action('wp_head', [$this, 'preloadFonts'], -2); + // Variables CSS: P:-1 (antes de CriticalBootstrapService P:0) add_action('wp_head', [$this, 'injectVariables'], -1); @@ -36,6 +49,25 @@ final class CriticalCSSInjector add_action('wp_enqueue_scripts', [$this, 'dequeueInlinedCSS'], 999); } + /** + * Inyecta preload links para fuentes criticas + * + * Resuelve el problema de "font swap" donde el fallback (106% size-adjust) + * causa un salto visual cuando Poppins se carga. + * Con preload, las fuentes llegan antes del primer paint. + */ + public function preloadFonts(): void + { + echo "\n"; + + foreach (self::CRITICAL_FONTS as $font) { + printf( + '' . "\n", + esc_url(get_template_directory_uri() . $font) + ); + } + } + /** * Inyecta variables CSS criticas */