Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix handling IMG tags with JS-based lazy-loading #1785

Draft
wants to merge 2 commits into
base: trunk
Choose a base branch
from

Conversation

westonruter
Copy link
Member

On quite a few sites I found JS-based lazy-loading causing problems with Image Prioritizer. In particular, the Avada theme's Fusion Images lazy-loading functionality replaces srcset with data-srcset but it doesn't change the src, for example:

<img
	src="https://example.com/foo.webp"
	data-orig-src="https://example.com/foo.webp"
	width="1000"
	height="800"
	class="lazyload wp-image-1"
	srcset="data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20width%3D%271000%27%20height%3D%27800%27%20viewBox%3D%270%200%201000%20800%27%3E%3Crect%20width%3D%271000%27%20height%3D%27800%27%20fill-opacity%3D%220%22%2F%3E%3C%2Fsvg%3E"
	data-srcset="https://example.com/foo-200x91.webp 200w, https://example.com/foo-300x136.webp 300w, https://example.com/foo-400x181.webp 400w, https://example.com/foo-600x272.webp 600w, https://example.com/foo-768x348.webp 768w, https://example.com/foo-800x362.webp 800w, https://example.com/foo-1024x463.webp 1024w, https://example.com/foo-1200x543.webp 1200w, https://example.com/foo-1536x695.webp 1536w, https://example.com/foo.webp 1920w"
	data-sizes="auto"
	data-orig-sizes="(max-width: 767px) 100vw, 1920px"
>

This was resulting in an erroneous preload link being added, in particular the imagesrcset is pointing to a data: URL:

<link data-od-added-tag rel="preload" fetchpriority="high" as="image" href="https://example.com/foo.webp" imagesrcset="data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20width%3D%271000%27%20height%3D%27800%27%20viewBox%3D%270%200%201000%20800%27%3E%3Crect%20width%3D%271000%27%20height%3D%27800%27%20fill-opacity%3D%220%22%2F%3E%3C%2Fsvg%3E" media="screen and (min-width: 783px)">

So this PR adds checks to make sure that if an IMG has such a srcset it is also excluded from processing.

In a future PR we could consider undoing such JS-based lazy-loading, rewriting data-src to src, data-srcset back to srcset and so on, and then to process the IMG as normal. This would have a dramatic improvement to LCP especially when the such JS-based lazy-loading is being done for images in the initial viewport, especially for an IMG which is the LCP element. See #1746.

@westonruter westonruter added [Type] Bug An existing feature is broken [Plugin] Image Prioritizer Issues for the Image Prioritizer plugin (dependent on Optimization Detective) labels Jan 9, 2025
@westonruter westonruter added this to the image-prioritizer n.e.x.t milestone Jan 9, 2025
return false;
}

// Abort if the srcset is a data: URL since there is nothing to optimize.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, there could be something to optimize. We can't preload the URL, but we could still add fetchpriority=high to the IMG.

@@ -53,13 +97,21 @@ public function __invoke( OD_Tag_Visitor_Context $context ): bool {
* @return bool Whether the tag should be tracked in URL Metrics.
*/
private function process_img( OD_HTML_Tag_Processor $processor, OD_Tag_Visitor_Context $context ): bool {
$src = $this->get_valid_src( $processor );
if ( null === $src ) {
if ( ! $this->is_img_with_valid_src_and_srcset( $processor ) ) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As noted below, this may be too conservative. We could still process this IMG. It's just we would skip any parts related to preloading the src or srcset.

Copy link

codecov bot commented Jan 9, 2025

Codecov Report

Attention: Patch coverage is 96.29630% with 1 line in your changes missing coverage. Please review.

Project coverage is 57.52%. Comparing base (d656e11) to head (e046d70).

Files with missing lines Patch % Lines
...itizer/class-image-prioritizer-img-tag-visitor.php 96.29% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##            trunk    #1785      +/-   ##
==========================================
+ Coverage   57.43%   57.52%   +0.08%     
==========================================
  Files          84       84              
  Lines        6508     6519      +11     
==========================================
+ Hits         3738     3750      +12     
+ Misses       2770     2769       -1     
Flag Coverage Δ
multisite 57.52% <96.29%> (+0.08%) ⬆️
single 34.40% <0.00%> (-0.06%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Plugin] Image Prioritizer Issues for the Image Prioritizer plugin (dependent on Optimization Detective) [Type] Bug An existing feature is broken
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant