← All changes
|
includes/modules/ResourceHints/ResourceHintsModule.php
+49
-15
1.3.2
→
1.4.1
View file →
| @@ -59,9 +59,10 @@ | ||
| 59 | 59 | return array( |
| 60 | 60 | 'label' => __( 'Resource Hints', 'xspeed' ), |
| 61 | 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.', 'xspeed' ), | |
| 63 | + 'description' => __( 'Tells the browser to fetch the main image and fonts early.', 'xspeed' ), | |
| 64 | + 'group' => 'performance', | |
| 64 | 65 | // Host page: Hints (this module) + a Speculation Rules section |
| 65 | 66 | // (SmartPredict, Pro). SmartPredict prefetches the next page in |
| 66 | 67 | // the visitor's browser — same family as preload/preconnect, so |
| 67 | 68 | // it belongs here, not under AI (FBS-83633). |
| @@ -73,16 +74,17 @@ | ||
| 73 | 74 | return array( |
| 74 | 75 | 'enabled' => array( |
| 75 | 76 | 'type' => 'bool', |
| 76 | 77 | 'default' => true, |
| 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' ), | |
| 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' ), | |
| 79 | 80 | ), |
| 80 | 81 | 'lcp_preload' => array( |
| 81 | 82 | 'type' => 'bool', |
| 82 | 83 | 'default' => true, |
| 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' ), | |
| 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' ), | |
| 85 | 87 | ), |
| 86 | 88 | 'lcp_image_count' => array( |
| 87 | 89 | 'type' => 'int', |
| 88 | 90 | 'default' => 1, |
| @@ -87,37 +89,44 @@ | ||
| 87 | 89 | 'type' => 'int', |
| 88 | 90 | 'default' => 1, |
| 89 | 91 | 'min' => 0, |
| 90 | 92 | 'max' => 3, |
| 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 | + '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' ), | |
| 93 | 97 | ), |
| 94 | 98 | 'lcp_exclusions' => array( |
| 95 | 99 | 'type' => 'list', |
| 96 | 100 | 'default' => array(), |
| 97 | 101 | 'item_type' => 'string', |
| 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' ), | |
| 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' ), | |
| 100 | 105 | ), |
| 101 | 106 | 'preload_images' => array( |
| 102 | 107 | 'type' => 'list', |
| 103 | 108 | 'default' => array(), |
| 104 | 109 | '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' ), | |
| 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' ), | |
| 107 | 113 | ), |
| 108 | 114 | 'preconnect' => array( |
| 109 | 115 | 'type' => 'bool', |
| 110 | 116 | 'default' => true, |
| 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' ), | |
| 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' ), | |
| 113 | 120 | ), |
| 114 | 121 | 'preconnect_hosts' => array( |
| 115 | 122 | 'type' => 'list', |
| 116 | 123 | 'default' => array(), |
| 117 | 124 | 'item_type' => 'url', |
| 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' ), | |
| 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' ), | |
| 120 | 129 | ), |
| 121 | 130 | ); |
| 122 | 131 | } |
| 123 | 132 | |
| @@ -231,9 +240,34 @@ | ||
| 231 | 240 | if ( is_array( $lazy ) && ! empty( $lazy['lazy_images'] ) && ! empty( $lazy['excluded_images'] ) && is_array( $lazy['excluded_images'] ) ) { |
| 232 | 241 | $opts['eager_excluded_images'] = array_values( array_filter( array_map( 'strval', $lazy['excluded_images'] ) ) ); |
| 233 | 242 | } |
| 234 | 243 | } |
| 244 | + $opts['page_url'] = self::current_page_url(); | |
| 235 | 245 | return $opts; |
| 246 | + } | |
| 247 | + | |
| 248 | + /** | |
| 249 | + * The URL of the page being served, for the LCP preload candidate seam. | |
| 250 | + * Empty outside a request (CLI, tests). | |
| 251 | + * | |
| 252 | + * The site's scheme and host with the request path as the browser sent | |
| 253 | + * it. Not home_url( REQUEST_URI ): on a site in a subfolder both carry the | |
| 254 | + * folder, which then appeared twice. And not sanitize_text_field(), which | |
| 255 | + * drops percent-encoded octets, so `/caf%C3%A9/` lost its é. | |
| 256 | + */ | |
| 257 | + private static function current_page_url(): string { | |
| 258 | + if ( ! isset( $_SERVER['REQUEST_URI'] ) || ! function_exists( 'home_url' ) ) { | |
| 259 | + return ''; | |
| 260 | + } | |
| 261 | + $uri = esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ); | |
| 262 | + if ( '' === $uri || '/' !== $uri[0] ) { | |
| 263 | + return ''; | |
| 264 | + } | |
| 265 | + $home = wp_parse_url( home_url( '/' ) ); | |
| 266 | + $scheme = isset( $home['scheme'] ) ? $home['scheme'] : 'https'; | |
| 267 | + $host = isset( $home['host'] ) ? $home['host'] : ''; | |
| 268 | + $port = isset( $home['port'] ) ? ':' . $home['port'] : ''; | |
| 269 | + return '' === $host ? '' : $scheme . '://' . $host . $port . $uri; | |
| 236 | 270 | } |
| 237 | 271 | |
| 238 | 272 | public function cli_commands(): array { |
| 239 | 273 | return array( |