← All changes
|
includes/modules/ResourceHints/ResourceHintsModule.php
+47
-15
1.2.0
→
1.3.2
View file →
| @@ -56,12 +56,12 @@ | ||
| 56 | 56 | private static $buffering = false; |
| 57 | 57 | |
| 58 | 58 | public function ui_metadata(): array { |
| 59 | 59 | return array( |
| 60 | - 'label' => 'Resource Hints', | |
| 61 | - 'tab_label' => 'Hints', // its own tab on the Resource Hints page | |
| 60 | + 'label' => __( 'Resource Hints', 'xspeed' ), | |
| 61 | + 'tab_label' => __( 'Hints', 'xspeed' ), // its own tab on the Resource Hints page | |
| 62 | 62 | 'icon' => 'Zap', |
| 63 | - 'description' => 'Preload the LCP hero image and preconnect to font hosts so the largest element paints sooner.', | |
| 63 | + 'description' => __( 'Preload the LCP hero image and preconnect to font hosts so the largest element paints sooner.', 'xspeed' ), | |
| 64 | 64 | // Host page: Hints (this module) + a Speculation Rules section |
| 65 | 65 | // (SmartPredict, Pro). SmartPredict prefetches the next page in |
| 66 | 66 | // the visitor's browser — same family as preload/preconnect, so |
| 67 | 67 | // it belongs here, not under AI (FBS-83633). |
| @@ -73,16 +73,16 @@ | ||
| 73 | 73 | return array( |
| 74 | 74 | 'enabled' => array( |
| 75 | 75 | 'type' => 'bool', |
| 76 | 76 | 'default' => true, |
| 77 | - 'label' => 'Enable Resource Hints', | |
| 78 | - 'description' => 'Master switch for the LCP-image preload + preconnect resource hints. On by default — these are safe, no-config optimizations that help every theme.', | |
| 77 | + 'label' => __( 'Enable Resource Hints', 'xspeed' ), | |
| 78 | + 'description' => __( 'Master switch for the LCP-image preload + preconnect resource hints. On by default — these are safe, no-config optimizations that help every theme.', 'xspeed' ), | |
| 79 | 79 | ), |
| 80 | 80 | 'lcp_preload' => array( |
| 81 | 81 | 'type' => 'bool', |
| 82 | 82 | 'default' => true, |
| 83 | - 'label' => 'Preload LCP Image', | |
| 84 | - 'description' => 'Detect the largest above-the-fold image and emit a <link rel="preload" as="image" fetchpriority="high"> in the head, plus fetchpriority="high" on the image. This is the highest-impact fix for Largest Contentful Paint — it beats any lazy-load the theme applied.', | |
| 83 | + 'label' => __( 'Preload LCP Image', 'xspeed' ), | |
| 84 | + 'description' => __( 'Detect the largest above-the-fold image and emit a <link rel="preload" as="image" fetchpriority="high"> in the head, plus fetchpriority="high" on the image. This is the highest-impact fix for Largest Contentful Paint — it beats any lazy-load the theme applied.', 'xspeed' ), | |
| 85 | 85 | ), |
| 86 | 86 | 'lcp_image_count' => array( |
| 87 | 87 | 'type' => 'int', |
| 88 | 88 | 'default' => 1, |
| @@ -87,35 +87,61 @@ | ||
| 87 | 87 | 'type' => 'int', |
| 88 | 88 | 'default' => 1, |
| 89 | 89 | 'min' => 0, |
| 90 | 90 | 'max' => 3, |
| 91 | - 'label' => 'Images to Preload', | |
| 92 | - 'description' => 'How many of the first images on the page to preload. 1 is right for most sites (the single hero). Raise it only if the fold shows a small gallery.', | |
| 91 | + 'label' => __( 'Images to Preload', 'xspeed' ), | |
| 92 | + 'description' => __( 'How many of the first images on the page to preload. 1 is right for most sites (the single hero). Raise it only if the fold shows a small gallery.', 'xspeed' ), | |
| 93 | 93 | ), |
| 94 | 94 | 'lcp_exclusions' => array( |
| 95 | 95 | 'type' => 'list', |
| 96 | 96 | 'default' => array(), |
| 97 | 97 | 'item_type' => 'string', |
| 98 | - 'label' => 'Exclude From Preload', | |
| 99 | - 'description' => 'Substring patterns (filename or class) that, if found in an <img>, exempt it from being treated as the LCP image. Useful for tracking pixels, spacers, or a decorative first image that is not the hero.', | |
| 98 | + 'label' => __( 'Exclude From Preload', 'xspeed' ), | |
| 99 | + 'description' => __( 'Substring patterns (filename or class) that, if found in an <img>, exempt it from being treated as the LCP image. Useful for tracking pixels, spacers, or a decorative first image that is not the hero.', 'xspeed' ), | |
| 100 | 100 | ), |
| 101 | + 'preload_images' => array( | |
| 102 | + 'type' => 'list', | |
| 103 | + 'default' => array(), | |
| 104 | + 'item_type' => 'string', | |
| 105 | + 'label' => __( 'Always Preload These Images', 'xspeed' ), | |
| 106 | + 'description' => __( 'Image URLs (full or site-relative) to preload with high priority on every page. This is the escape hatch for an LCP image the detector cannot see — most often a hero section\'s CSS background-image, which carries none of the signals the automatic pick reads. Keep it to one or two images: preloading many hands them all top network priority and the page itself loses. The first three entries are used.', 'xspeed' ), | |
| 107 | + ), | |
| 101 | 108 | 'preconnect' => array( |
| 102 | 109 | 'type' => 'bool', |
| 103 | 110 | 'default' => true, |
| 104 | - 'label' => 'Preconnect to Font Hosts', | |
| 105 | - 'description' => 'When Google Fonts are detected, emit <link rel="preconnect"> to fonts.googleapis.com and fonts.gstatic.com so the DNS + TLS handshake happens ahead of the font request instead of on the critical path.', | |
| 111 | + 'label' => __( 'Preconnect to Font Hosts', 'xspeed' ), | |
| 112 | + 'description' => __( 'When Google Fonts are detected, emit <link rel="preconnect"> to fonts.googleapis.com and fonts.gstatic.com so the DNS + TLS handshake happens ahead of the font request instead of on the critical path.', 'xspeed' ), | |
| 106 | 113 | ), |
| 107 | 114 | 'preconnect_hosts' => array( |
| 108 | 115 | 'type' => 'list', |
| 109 | 116 | 'default' => array(), |
| 110 | 117 | 'item_type' => 'url', |
| 111 | - 'label' => 'Extra Preconnect Hosts', | |
| 112 | - 'description' => 'One origin per line (e.g. https://cdn.example.com) to preconnect in addition to the auto-detected font hosts. Use for a CDN or third-party origin that serves above-the-fold assets.', | |
| 118 | + 'label' => __( 'Extra Preconnect Hosts', 'xspeed' ), | |
| 119 | + 'description' => __( 'One origin per line (e.g. https://cdn.example.com) to preconnect in addition to the auto-detected font hosts. Use for a CDN or third-party origin that serves above-the-fold assets.', 'xspeed' ), | |
| 113 | 120 | ), |
| 114 | 121 | ); |
| 115 | 122 | } |
| 116 | 123 | |
| 117 | 124 | public function boot(): void { |
| 125 | + /* | |
| 126 | + * Deferred to `init`. This module reads its own settings to decide | |
| 127 | + * what to hook, and reading settings builds settings_schema(), whose | |
| 128 | + * labels are declared through __(). boot() runs on `plugins_loaded`, | |
| 129 | + * before `after_setup_theme` — the point WordPress 6.7+ treats as the | |
| 130 | + * earliest safe moment to translate — so doing that here fires | |
| 131 | + * _load_textdomain_just_in_time on every request AND resolves the | |
| 132 | + * labels against a domain that is not loaded yet. | |
| 133 | + * | |
| 134 | + * Everything below hooks actions that fire after `init`, so running | |
| 135 | + * one hook later is equivalent. | |
| 136 | + */ | |
| 137 | + add_action( 'init', array( $this, 'boot_on_init' ) ); | |
| 138 | + } | |
| 139 | + | |
| 140 | + /** | |
| 141 | + * The real boot body — see boot() for why it runs on `init`. | |
| 142 | + */ | |
| 143 | + public function boot_on_init(): void { | |
| 118 | 144 | // Frontend page renders only. Admin / feed / cron / AJAX / REST never |
| 119 | 145 | // produce an HTML document we should rewrite. |
| 120 | 146 | if ( is_admin() |
| 121 | 147 | || ( defined( 'DOING_AJAX' ) && DOING_AJAX ) |
| @@ -120,8 +146,12 @@ | ||
| 120 | 146 | if ( is_admin() |
| 121 | 147 | || ( defined( 'DOING_AJAX' ) && DOING_AJAX ) |
| 122 | 148 | || ( defined( 'DOING_CRON' ) && DOING_CRON ) |
| 123 | 149 | || ( defined( 'REST_REQUEST' ) && REST_REQUEST ) |
| 150 | + // Builder editing screens are front-end URLs; injecting hints into | |
| 151 | + // the editor document helps nobody and can preload the wrong | |
| 152 | + // assets. (#281) | |
| 153 | + || \XSpeed\Builder_Editor::is_active() | |
| 124 | 154 | ) { |
| 125 | 155 | return; |
| 126 | 156 | } |
| 127 | 157 | |
| @@ -210,8 +240,9 @@ | ||
| 210 | 240 | array( |
| 211 | 241 | 'name' => 'xspeed resource-hints', |
| 212 | 242 | 'callback' => array( $this, 'cli_handler' ), |
| 213 | 243 | 'shortdesc' => 'Show LCP-preload / preconnect resource-hint settings.', |
| 244 | + 'ai_hint' => 'Browser resource hints — preload, prefetch, preconnect — for the resources that block first paint. Use for LCP problems or "preconnect to required origins" in PageSpeed. Not the same as the Preloader, which warms the page cache.', | |
| 214 | 245 | 'synopsis' => array(), |
| 215 | 246 | ), |
| 216 | 247 | ); |
| 217 | 248 | } |
| @@ -221,8 +252,9 @@ | ||
| 221 | 252 | \WP_CLI::log( sprintf( '%-20s %s', 'enabled', ! empty( $opts['enabled'] ) ? 'on' : 'off' ) ); |
| 222 | 253 | \WP_CLI::log( sprintf( '%-20s %s', 'lcp_preload', ! empty( $opts['lcp_preload'] ) ? 'on' : 'off' ) ); |
| 223 | 254 | \WP_CLI::log( sprintf( '%-20s %d', 'lcp_image_count', (int) ( $opts['lcp_image_count'] ?? 1 ) ) ); |
| 224 | 255 | \WP_CLI::log( sprintf( '%-20s %d pattern(s)', 'lcp_exclusions', count( (array) ( $opts['lcp_exclusions'] ?? array() ) ) ) ); |
| 256 | + \WP_CLI::log( sprintf( '%-20s %d url(s)', 'preload_images', count( (array) ( $opts['preload_images'] ?? array() ) ) ) ); | |
| 225 | 257 | \WP_CLI::log( sprintf( '%-20s %s', 'preconnect', ! empty( $opts['preconnect'] ) ? 'on' : 'off' ) ); |
| 226 | 258 | \WP_CLI::log( sprintf( '%-20s %d host(s)', 'preconnect_hosts', count( (array) ( $opts['preconnect_hosts'] ?? array() ) ) ) ); |
| 227 | 259 | } |
| 228 | 260 | } |