PluginProbe
xSpeed Cache: AI-Powered Performance Hub with MCP, Caching & CDN / 1.3.2
xSpeed Cache: AI-Powered Performance Hub with MCP, Caching & CDN v1.3.2
1.3.2 1.3.1 1.3.0 1.2.4 trunk 1.0.0 1.0.1 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.0.7 1.0.8 1.0.9 1.1.0 1.1.1 1.1.2 1.1.3 1.1.4 1.1.5 1.1.6 1.1.7 1.1.8 1.2.0 All 28 releases
← All changes | includes/modules/ResourceHints/ResourceHintsModule.php +47 -15 1.1.61.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 }