From 5cf2513a8d3d09358427c05fb31b940cc9e24aab Mon Sep 17 00:00:00 2001 From: Jasper Frumau Date: Mon, 24 Nov 2025 13:52:06 +0700 Subject: [PATCH] Expanded Async CSS Loading --- CHANGELOG.md | 20 ++++++++++++++++++++ app/filters.php | 25 +++++++++++++++++++++++-- style.css | 2 +- 3 files changed, 44 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8589e15..9e55c58 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,26 @@ 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.16] - 2025-11-24 + +### Added +- **Speed Optimization: Expanded Async CSS Loading** ([filters.php:85-129](app/filters.php#L85-L129)) + - Added WordPress core `wp-block-library` (15.7 KiB) to async loading + - Added all 15 custom Imagewize block styles to async loading + - Fixed `brands-styles` handle (was incorrectly `wc-brands-styles`) + - **Impact**: ~300-400ms render-blocking time savings + +### Fixed +- **WooCommerce Shop Grid Layout**: Fixed critical bug where shop page showed 2 columns instead of 4 + - **Root cause**: `woocommerce-smallscreen` CSS has `media='only screen and (max-width: 768px)'` + - Using `preg_replace` to change ANY media query to `print` then swap to `all` broke responsive behavior + - Mobile-only styles (2-column grid) were applying at ALL viewport sizes + - **Solution**: Excluded `woocommerce-smallscreen` from async list, reverted to `str_replace` targeting only `media='all'` + - **Lesson**: Never async-load stylesheets with specific media queries - it destroys their responsive behavior + +### Documentation +- Updated `docs/nynaeve/SPEED-TWEAKS.md` with Phase 1 expansion details and critical warning about media queries + ## [2.0.15] - 2025-11-24 ### Added diff --git a/app/filters.php b/app/filters.php index b2bef2a..03b21dd 100644 --- a/app/filters.php +++ b/app/filters.php @@ -84,21 +84,42 @@ function my_acf_json_save_point($path) */ add_filter('style_loader_tag', function ($html, $handle) { // List of non-critical stylesheets to load asynchronously + // NOTE: Do NOT include stylesheets with specific media queries (like woocommerce-smallscreen) + // as the async technique would break their responsive behavior $async_styles = [ // Classic WooCommerce styles 'woocommerce-layout', - 'woocommerce-smallscreen', + // 'woocommerce-smallscreen', // EXCLUDED: Has media query for max-width:768px - must preserve! 'woocommerce-general', - 'wc-brands-styles', + 'brands-styles', // WooCommerce Brands plugin // WooCommerce Blocks styles 'wc-blocks-style', 'wc-blocks-vendors-style', + // WordPress core block library + 'wp-block-library', + // Custom block styles (below-the-fold on homepage) + 'imagewize-feature-list-grid-style', + 'imagewize-testimonial-grid-style', + 'imagewize-carousel-style', + 'imagewize-content-image-text-card-style', + 'imagewize-related-articles-style', + 'imagewize-pricing-style', + 'imagewize-pricing-tiers-style', + 'imagewize-faq-style', + 'imagewize-cta-columns-style', + 'imagewize-cta-block-blue-style', + 'imagewize-about-style', + 'imagewize-review-profiles-style', + 'imagewize-two-column-card-style', + 'imagewize-multi-column-content-style', + 'imagewize-page-heading-blue-style', // Other 'slick-carousel', ]; if (in_array($handle, $async_styles, true)) { // Change media to print, swap to all on load + // Only target media='all' to preserve specific media queries $html = str_replace( "media='all'", "media='print' onload=\"this.media='all'\"", diff --git a/style.css b/style.css index 038d83b..42c62c0 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.15 +Version: 2.0.16 Author: Jasper Frumau Author URI: https://magewize.com Text Domain: nynaeve