diff --git a/CHANGELOG.md b/CHANGELOG.md index 9e55c58..36350e5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,28 @@ All notable changes to the Nynaeve theme will be documented in this file. For project-wide changes (infrastructure, tooling, cross-cutting concerns), see the [project root CHANGELOG.md](../../../../../CHANGELOG.md). +## [2.0.17] - 2025-11-24 + +### Fixed +- **Speed Optimization: Hero Image Eager Loading** ([HeroBlock.php:181-198](app/Blocks/HeroBlock.php#L181-L198)) + - Changed hero desktop image from `loading="lazy"` to `loading="eager"` + - Added `fetchpriority="high"` attribute to prioritize LCP image download + - **Root cause**: Lazy loading the LCP (Largest Contentful Paint) image caused 2,360ms "Resource load delay" + - Browser was waiting to determine if image was in viewport before loading + - **Impact**: ~2+ seconds LCP improvement expected + +### Added +- **Speed Optimization: Font Preloading** ([setup.php:400-436](app/setup.php#L400-L436)) + - Added preload hints for Open Sans regular (400) and semibold (600) fonts + - Fonts are preloaded early in `` before CSS parsing begins + - Uses Vite manifest to resolve hashed font filenames + - **Root cause**: CLS (Cumulative Layout Shift) of 0.602 caused by late font loading + - When Open Sans loaded after initial render, text reflowed and shifted layout + - **Impact**: CLS reduction expected (target < 0.1) + +### Documentation +- Updated `docs/nynaeve/SPEED-TWEAKS.md` with new optimizations 8, 9, and 10 + ## [2.0.16] - 2025-11-24 ### Added diff --git a/app/Blocks/HeroBlock.php b/app/Blocks/HeroBlock.php index 8cac7e0..91da564 100644 --- a/app/Blocks/HeroBlock.php +++ b/app/Blocks/HeroBlock.php @@ -180,6 +180,7 @@ public function with(): array // Generate responsive image HTML for desktop // Uses 'hero-desktop' size (600x348) with srcset for retina (1200x696) + // IMPORTANT: Hero image is the LCP element - must use eager loading, not lazy $desktop_image_html = ''; $desktop_image_alt_value = $desktop_image['alt'] ?? ($desktop_image['title'] ?? 'Desktop image'); if (! empty($desktop_image['ID'])) { @@ -189,7 +190,8 @@ public function with(): array false, [ 'class' => 'desktop-only-img object-cover w-full h-full', - 'loading' => 'lazy', + 'loading' => 'eager', + 'fetchpriority' => 'high', 'sizes' => '(min-width: 1024px) 576px, 50vw', ] ); diff --git a/app/setup.php b/app/setup.php index f0d835d..9ce2df6 100644 --- a/app/setup.php +++ b/app/setup.php @@ -396,3 +396,41 @@ class="text-center w-full px-4 py-3 bg-indigo-600 flex items-center ], ]); }, 10, 2); + +/** + * Preload critical fonts to reduce CLS (Cumulative Layout Shift). + * + * Open Sans is the primary body font and causes significant layout shift (CLS 0.602) + * when it loads late. Preloading tells the browser to fetch it early, before CSS parsing. + * + * @link https://web.dev/preload-critical-assets/ + * @link https://web.dev/optimize-cls/#web-fonts-causing-foit/fout + */ +add_action('wp_head', function () { + // Get the Vite manifest to find the hashed font filename + $manifest_path = get_theme_file_path('public/build/manifest.json'); + + if (! file_exists($manifest_path)) { + return; + } + + $manifest = json_decode(file_get_contents($manifest_path), true); + + if (! is_array($manifest)) { + return; + } + + // Preload Open Sans regular (400) - most commonly used weight + $font_key = 'resources/fonts/open-sans-v40-latin-regular.woff2'; + if (isset($manifest[$font_key]['file'])) { + $font_url = get_theme_file_uri('public/build/'.$manifest[$font_key]['file']); + echo ''."\n"; + } + + // Preload Open Sans semibold (600) - used for headings and emphasis + $font_key_600 = 'resources/fonts/open-sans-v40-latin-600.woff2'; + if (isset($manifest[$font_key_600]['file'])) { + $font_url_600 = get_theme_file_uri('public/build/'.$manifest[$font_key_600]['file']); + echo ''."\n"; + } +}, 1); // Priority 1 to run very early in diff --git a/style.css b/style.css index 42c62c0..f420306 100644 --- a/style.css +++ b/style.css @@ -2,7 +2,7 @@ Theme Name: Nynaeve Theme URI: https://imagewize.com Description: Modern WordPress theme built on Sage 11 with reusable custom blocks using WordPress native tools and the Roots.io stack. -Version: 2.0.16 +Version: 2.0.17 Author: Jasper Frumau Author URI: https://magewize.com Text Domain: nynaeve