PluginProbe
xSpeed Cache: AI-Powered Performance Hub with MCP, Caching & CDN / 1.3.7
xSpeed Cache: AI-Powered Performance Hub with MCP, Caching & CDN v1.3.7
1.3.7 1.3.6 1.3.5 1.3.4 1.3.3 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 All 33 releases
← All changes | includes/modules/ResourceHints/ResourceHintsModule.php +62 -15 1.0.8 → 1.3.7 View file →
@@ -56,11 +56,18 @@
56 56 private static $buffering = false;
57 57
58 58 public function ui_metadata(): array {
59 59 return array(
60 - 'label' => 'Resource Hints',
61 - 'icon' => 'Zap',
62 - 'description' => 'Preload the LCP hero image and preconnect to font hosts so the largest element paints sooner.',
60 + 'label' => __( 'Resource Hints', 'xspeed' ),
61 + 'tab_label' => __( 'Hints', 'xspeed' ), // its own tab on the Resource Hints page
62 + 'icon' => 'Zap',
63 + 'description' => __( 'Tells the browser to fetch the main image and fonts early.', 'xspeed' ),
64 + 'group' => 'performance',
65 + // Host page: Hints (this module) + a Speculation Rules section
66 + // (SmartPredict, Pro). SmartPredict prefetches the next page in
67 + // the visitor's browser — same family as preload/preconnect, so
68 + // it belongs here, not under AI (FBS-83633).
69 + 'custom_panel' => 'ResourceHintsPanel',
63 70 );
64 71 }
65 72
66 73 public function settings_schema(): array {
@@ -67,16 +74,17 @@
67 74 return array(
68 75 'enabled' => array(
69 76 'type' => 'bool',
70 77 'default' => true,
71 - 'label' => 'Enable Resource Hints',
72 - 'description' => 'Master switch for the LCP-image preload + preconnect resource hints. On by default — these are safe, no-config optimizations that help every theme.',
78 + 'label' => __( 'Enable resource hints', 'xspeed' ),
79 + 'description' => __( 'Turns on all the hints below. They are safe on every theme, so this is on by default.', 'xspeed' ),
73 80 ),
74 81 'lcp_preload' => array(
75 82 'type' => 'bool',
76 83 'default' => true,
77 - 'label' => 'Preload LCP Image',
78 - '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.',
84 + 'label' => __( 'Preload the main image', 'xspeed' ),
85 + 'description' => __( 'Finds the largest image at the top of the page and tells the browser to fetch it first. This usually gives the biggest LCP gain.', 'xspeed' ),
86 + 'dependsOn' => array( 'field' => 'enabled' ),
79 87 ),
80 88 'lcp_image_count' => array(
81 89 'type' => 'int',
82 90 'default' => 1,
@@ -81,35 +89,68 @@
81 89 'type' => 'int',
82 90 'default' => 1,
83 91 'min' => 0,
84 92 'max' => 3,
85 - 'label' => 'Images to Preload',
86 - '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.',
93 + 'label' => __( 'Images to preload', 'xspeed' ),
94 + 'description' => __( 'How many images at the top of the page to preload. 1 suits most sites; raise it only if the top shows a small gallery.', 'xspeed' ),
95 + 'advanced' => true,
96 + 'dependsOn' => array( 'field' => 'lcp_preload' ),
87 97 ),
88 98 'lcp_exclusions' => array(
89 99 'type' => 'list',
90 100 'default' => array(),
91 101 'item_type' => 'string',
92 - 'label' => 'Exclude From Preload',
93 - '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.',
102 + 'label' => __( 'Excluded from preload', 'xspeed' ),
103 + 'description' => __( 'Images whose tag contains a line here, such as a file name or class, are never picked as the main image. Useful for tracking pixels and spacers.', 'xspeed' ),
104 + 'dependsOn' => array( 'field' => 'lcp_preload' ),
94 105 ),
106 + 'preload_images' => array(
107 + 'type' => 'list',
108 + 'default' => array(),
109 + 'item_type' => 'string',
110 + 'label' => __( 'Always preload these images', 'xspeed' ),
111 + 'description' => __( 'Image URLs to fetch first on every page, such as a hero background set in CSS. Keep it to one or two; only the first three are used.', 'xspeed' ),
112 + 'dependsOn' => array( 'field' => 'enabled' ),
113 + ),
95 114 'preconnect' => array(
96 115 'type' => 'bool',
97 116 'default' => true,
98 - 'label' => 'Preconnect to Font Hosts',
99 - '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.',
117 + 'label' => __( 'Connect early to Google Fonts', 'xspeed' ),
118 + 'description' => __( 'When the page uses Google Fonts, the browser connects to Google\'s servers early, so fonts arrive sooner.', 'xspeed' ),
119 + 'dependsOn' => array( 'field' => 'enabled' ),
100 120 ),
101 121 'preconnect_hosts' => array(
102 122 'type' => 'list',
103 123 'default' => array(),
104 124 'item_type' => 'url',
105 - 'label' => 'Extra Preconnect Hosts',
106 - '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.',
125 + 'label' => __( 'Other domains to connect early', 'xspeed' ),
126 + 'description' => __( 'One address per line, such as https://cdn.example.com. Use for a CDN or other domain that serves files at the top of the page.', 'xspeed' ),
127 + 'advanced' => true,
128 + 'dependsOn' => array( 'field' => 'enabled' ),
107 129 ),
108 130 );
109 131 }
110 132
111 133 public function boot(): void {
134 + /*
135 + * Deferred to `init`. This module reads its own settings to decide
136 + * what to hook, and reading settings builds settings_schema(), whose
137 + * labels are declared through __(). boot() runs on `plugins_loaded`,
138 + * before `after_setup_theme` — the point WordPress 6.7+ treats as the
139 + * earliest safe moment to translate — so doing that here fires
140 + * _load_textdomain_just_in_time on every request AND resolves the
141 + * labels against a domain that is not loaded yet.
142 + *
143 + * Everything below hooks actions that fire after `init`, so running
144 + * one hook later is equivalent.
145 + */
146 + add_action( 'init', array( $this, 'boot_on_init' ) );
147 + }
148 +
149 + /**
150 + * The real boot body — see boot() for why it runs on `init`.
151 + */
152 + public function boot_on_init(): void {
112 153 // Frontend page renders only. Admin / feed / cron / AJAX / REST never
113 154 // produce an HTML document we should rewrite.
114 155 if ( is_admin()
115 156 || ( defined( 'DOING_AJAX' ) && DOING_AJAX )
@@ -114,8 +155,12 @@
114 155 if ( is_admin()
115 156 || ( defined( 'DOING_AJAX' ) && DOING_AJAX )
116 157 || ( defined( 'DOING_CRON' ) && DOING_CRON )
117 158 || ( defined( 'REST_REQUEST' ) && REST_REQUEST )
159 + // Builder editing screens are front-end URLs; injecting hints into
160 + // the editor document helps nobody and can preload the wrong
161 + // assets. (#281)
162 + || \XSpeed\Builder_Editor::is_active()
118 163 ) {
119 164 return;
120 165 }
121 166
@@ -204,8 +249,9 @@
204 249 array(
205 250 'name' => 'xspeed resource-hints',
206 251 'callback' => array( $this, 'cli_handler' ),
207 252 'shortdesc' => 'Show LCP-preload / preconnect resource-hint settings.',
253 + '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.',
208 254 'synopsis' => array(),
209 255 ),
210 256 );
211 257 }
@@ -215,8 +261,9 @@
215 261 \WP_CLI::log( sprintf( '%-20s %s', 'enabled', ! empty( $opts['enabled'] ) ? 'on' : 'off' ) );
216 262 \WP_CLI::log( sprintf( '%-20s %s', 'lcp_preload', ! empty( $opts['lcp_preload'] ) ? 'on' : 'off' ) );
217 263 \WP_CLI::log( sprintf( '%-20s %d', 'lcp_image_count', (int) ( $opts['lcp_image_count'] ?? 1 ) ) );
218 264 \WP_CLI::log( sprintf( '%-20s %d pattern(s)', 'lcp_exclusions', count( (array) ( $opts['lcp_exclusions'] ?? array() ) ) ) );
265 + \WP_CLI::log( sprintf( '%-20s %d url(s)', 'preload_images', count( (array) ( $opts['preload_images'] ?? array() ) ) ) );
219 266 \WP_CLI::log( sprintf( '%-20s %s', 'preconnect', ! empty( $opts['preconnect'] ) ? 'on' : 'off' ) );
220 267 \WP_CLI::log( sprintf( '%-20s %d host(s)', 'preconnect_hosts', count( (array) ( $opts['preconnect_hosts'] ?? array() ) ) ) );
221 268 }
222 269 }