-
Notifications
You must be signed in to change notification settings - Fork 138
Description
Bug Description
On my site I'm using the Jetpack Image CDN (Photon). The LCP IMG element on the homepage is rendered by WordPress as:
<img
width="1200"
height="675"
src="https://weston.ruter.net/wp-content/uploads/2025/02/weston-ruter-beyond-1200x675.png"
class="attachment-post-thumbnail size-post-thumbnail wp-post-image"
alt="Boosting Performance with Optimization Detective"
style="width: 100%; height: 100%; object-fit: cover"
decoding="async"
fetchpriority="high"
srcset="
https://i0.wp.com/weston.ruter.net/wp-content/uploads/2025/02/weston-ruter-beyond.png?resize=1200%2C675&ssl=1 1200w,
https://i0.wp.com/weston.ruter.net/wp-content/uploads/2025/02/weston-ruter-beyond.png?resize=300%2C169&ssl=1 300w,
https://i0.wp.com/weston.ruter.net/wp-content/uploads/2025/02/weston-ruter-beyond.png?resize=700%2C394&ssl=1 700w,
https://i0.wp.com/weston.ruter.net/wp-content/uploads/2025/02/weston-ruter-beyond.png?resize=768%2C432&ssl=1 768w,
https://i0.wp.com/weston.ruter.net/wp-content/uploads/2025/02/weston-ruter-beyond.png?resize=1536%2C864&ssl=1 1536w,
https://i0.wp.com/weston.ruter.net/wp-content/uploads/2025/02/weston-ruter-beyond.png?resize=2048%2C1152&ssl=1 2048w,
https://i0.wp.com/weston.ruter.net/wp-content/uploads/2025/02/weston-ruter-beyond.png?resize=1980%2C1114&ssl=1 1980w,
https://i0.wp.com/weston.ruter.net/wp-content/uploads/2025/02/weston-ruter-beyond.png?resize=150%2C84&ssl=1 150w
"
sizes="(max-width: 1200px) 100vw, 1200px"
/>When Optimization Detective with Image Prioritizer runs, it identifies that this is the LCP element and it adds a preload link with fetchpriority=high, as expected:
<link
data-od-added-tag
rel="preload"
fetchpriority="high"
as="image"
href="https://weston.ruter.net/wp-content/uploads/2025/02/weston-ruter-beyond-1200x675.png"
imagesrcset="https://i0.wp.com/weston.ruter.net/wp-content/uploads/2025/02/weston-ruter-beyond.png?resize=1200%2C675&ssl=1 1200w, https://i0.wp.com/weston.ruter.net/wp-content/uploads/2025/02/weston-ruter-beyond.png?resize=300%2C169&ssl=1 300w, https://i0.wp.com/weston.ruter.net/wp-content/uploads/2025/02/weston-ruter-beyond.png?resize=700%2C394&ssl=1 700w, https://i0.wp.com/weston.ruter.net/wp-content/uploads/2025/02/weston-ruter-beyond.png?resize=768%2C432&ssl=1 768w, https://i0.wp.com/weston.ruter.net/wp-content/uploads/2025/02/weston-ruter-beyond.png?resize=1536%2C864&ssl=1 1536w, https://i0.wp.com/weston.ruter.net/wp-content/uploads/2025/02/weston-ruter-beyond.png?resize=2048%2C1152&ssl=1 2048w, https://i0.wp.com/weston.ruter.net/wp-content/uploads/2025/02/weston-ruter-beyond.png?resize=1980%2C1114&ssl=1 1980w, https://i0.wp.com/weston.ruter.net/wp-content/uploads/2025/02/weston-ruter-beyond.png?resize=150%2C84&ssl=1 150w"
imagesizes="(width <= 480px) 300px, (480px < width <= 600px) 455px, (600px < width <= 782px) 644px, (782px < width) 645px"
media="screen"
/>Nevertheless, when I look at the Chrome DevTools console I see an unexpected warning:
Warning
The resource was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate as value and it is preloaded intentionally. The resource https://i0.wp.com/weston.ruter.net/wp-content/uploads/2025/02/weston-ruter-beyond.png?resize=768,432&ssl=1 was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate as value and it is preloaded intentionally.
When I look at the network panel I see that there are two copies of this image being loaded:
One of the URLs is getting the comma percent-encoded (the one in the LINK tag) and Chrome isn't understanding the URLs are the same. This seems like a bug in Chromium because these two URLs should be normalized to be the same, I should think:
- https://i0.wp.com/weston.ruter.net/wp-content/uploads/2025/02/weston-ruter-beyond.png?resize=768,432&ssl=1
- https://i0.wp.com/weston.ruter.net/wp-content/uploads/2025/02/weston-ruter-beyond.png?resize=768%2C432&ssl=1
In any case, the problem is that there is a percent-encoding which was originally present in the URL which was stripped out:
performance/plugins/optimization-detective/class-od-link-collection.php
Lines 331 to 343 in db322a3
| private function encode_url_for_response_header( string $url ): string { | |
| $decoded_url = urldecode( $url ); | |
| // Encode characters not allowed in a URL per RFC 3986 (anything that is not among the reserved and unreserved characters). | |
| $encoded_url = (string) preg_replace_callback( | |
| '/[^A-Za-z0-9\-._~:\/?#\[\]@!$&\'()*+,;=]/', | |
| static function ( $matches ) { | |
| return rawurlencode( $matches[0] ); | |
| }, | |
| $decoded_url | |
| ); | |
| return esc_url_raw( $encoded_url ); | |
| } |
This originates in #1802 and #1866.
The issue is not limited to percent encodings in the query parameters either. If I try to percent-encode the "j" in the .jpg file extension as .%6Apg, I get the same issue. However, if I add a query parameter with percent-encoding for text which must be percent-encoded (e.g. Arabic text), then I do not experience this issue. For example:
<figure>
<img
src="https://upload.wikimedia.org/wikipedia/commons/8/8d/American_bison_k5680-1.jpg?arabic=%D8%A7%D9%84%D8%A8%D9%8A%D8%B3%D9%88%D9%86&hebrew=חנות"
alt="Bison"
style="max-width: 100%; height: auto; aspect-ratio: 1270 / 828"
/>
</figure>Results in this LINK tag:
<figure>
<img
src="https://upload.wikimedia.org/wikipedia/commons/8/8d/American_bison_k5680-1.jpg?arabic=%D8%A7%D9%84%D8%A8%D9%8A%D8%B3%D9%88%D9%86&hebrew=חנות"
alt="Bison"
style="max-width: 100%; height: auto; aspect-ratio: 1270 / 828"
/>
</figure>And this HTTP Link response header:
Link: <https://upload.wikimedia.org/wikipedia/commons/8/8d/American_bison_k5680-1.jpg?arabic=%D8%A7%D9%84%D8%A8%D9%8A%D8%B3%D9%88%D9%86&hebrew=%D7%97%D7%A0%D7%95%D7%AA>; rel="preload"; fetchpriority="high"; as="image"; media="screen and (782px < width)"Nevertheless, only entry URL shows up in the Network log:
So it appears that we need to (1) stop doing urldecode() and then (2) only encode the characters that must be encoded (while leaving any percent encodings in the URL intact).
Steps to reproduce
- Activate the Image Prioritizer plugin.
- Add a Custom HTML block with the following contents:
<figure>
<img
src="https://upload.wikimedia.org/wikipedia/commons/8/8d/American_bison_k5680-1.%6Apg?foo=bar%2Cbaz"
alt="Bison"
style="max-width: 100%; height: auto; aspect-ratio: 1270 / 828"
/>
</figure>- Visit the frontend to trigger URL Metric collection.
- Reload the page in which a preload link has been added.
- Look at Network panel to see two almost-identical image URLs being loaded with high priority, when there should only be one.
Metadata
Metadata
Assignees
Labels
Type
Projects
Status

