WordPress.org

Make WordPress Core

Opened 12 days ago

Last modified 8 days ago

#53675 assigned enhancement

Omit lazy-loading attribute on first content image/iframe

Reported by: flixos90 Owned by: flixos90
Milestone: 5.9 Priority: normal
Severity: normal Version: 5.5
Component: Media Keywords: needs-patch needs-unit-tests
Focuses: performance Cc:

Description

Per this web.dev article, lazy-loading elements above the fold can lead to slight regressions in the Largest Contentful Paint metric. Since WordPress core by default lazy-loads every image and iframe, this also includes those in the initial viewport which has shown to impact LCP in the field at scale. After analyzing the situation of the current core implementation and the theme ecosystem (see this post), it is worth refining the default behavior of WordPress, in order to provide a solid default lazy-loading experience for the most common layouts (e.g. single column, hero image).

Related: #50425

Change History (6)

#1 @westonruter
12 days ago

  • Version set to 5.5

I have a POC patch in plugin form linked to at https://core.trac.wordpress.org/ticket/50425#comment:14

#2 @Mte90
12 days ago

Just because of thinking, the various website I manage with different themes and plugins.
I think that the best idea should be something like a global that track how many executions of (as example) wp_get_attachment_image and on first element doesn't add that parameter.
With adding a filter to disable that behaviour.

I know that a global is not the best thing but in this way is more granular in all the website without asking every developer from blocks to theme developers.

#3 follow-up: @flixos90
11 days ago

@Mte90 A global counter is what I was thinking too. I also agree this should be filterable - I'd argue in addition to turning it off it would be useful for themes with specific layouts where more than the first image typically appears above the fold.

@westonruter This is close to what I did in the prototype plugin used for the analysis - the one thing missing from yours (as you mention in the other ticket) was archive support. It would be great if you could review the prototype plugin (see below) and leave your thoughts.

For reference, this Gist has the prototype plugin with the logic used during the analysis:

  • Increase a counter for every content image (covering featured images and post content images).
  • If the first image is encountered, prevent the loading="lazy" attribute from being added.
  • This works for both single post views and archive views - in an archive, only the first image from the first post will not be lazy-loaded.

This plugin uses a function parameter to control how many images to omit from being lazy-loaded. For the core implementation, we could e.g. introduce a filter to allow modification. A theme that e.g. displays a grid archive with 3 columns could then set the number of images to not lazy-load for archives to 3.

Another thing to note here is that the plugin only focuses on images. The core implementation should also count iframes in the same way, in a common counter - i.e. the first image or iframe won't be lazy-loaded.

#4 @Mte90
9 days ago

So for iframe I think that we can do it for oembed (and blocks) but not for custom added inside the posts but should be enough I guess.

Usually a lot of plugins creates widget with iframe like mailchimp or instagram but usually they are used in the footer, so if we cover the oembed I think that is a acceptable percentage of usage.

#5 @azaozz
9 days ago

  • Milestone changed from Awaiting Review to 5.9

lazy-loading elements above the fold can lead to slight regressions in the Largest Contentful Paint metric

Sounds like something that needs to be fixed in the web browsers? They seem to be in a much better position to "see" (or guess) when an image or an iframe will be above the fold. Having said that, WP can also try to improve the situation until this is fixed in the browsers.

For reference, this Gist has the prototype plugin
...
For the core implementation, we could e.g. introduce a filter to allow modification.

Right. The Gist looks good but seems the code in core will be quite different once implemented.

Usually a lot of plugins create widget with iframes...

Yes, but thinking these plugins should be adding the loading attribute to their HTML themselves. Such plugins can usually detect when a widget is at the top, in the sidebar, or in the footer.

Looking at FSE/template parts, can probably use the same approach as with widgets: while editing add loading="eager" when the image or iframe is expected to be at the top/above the fold, and loading="lazy" when in the middle of the page or in the footer.

Lets look at this during 5.9.

Last edited 9 days ago by azaozz (previous) (diff)

#6 in reply to: ↑ 3 @westonruter
8 days ago

Replying to flixos90:

@westonruter This is close to what I did in the prototype plugin used for the analysis - the one thing missing from yours (as you mention in the other ticket) was archive support. It would be great if you could review the prototype plugin (see below) and leave your thoughts.

Actually, my plugin does account for the archive template. My comment was referring to how twentytwentyone was not omitting loading=lazy from the first post's featured image on an archive template.

In your POC, you're stripping out loading="lazy" from the HTML of the featured image. Would it not be better to rather filter wp_lazy_loading_enabled? See alternative.

It's good how you're using wp_img_tag_add_loading_attr to account for markup in the content beyond just the featured image.

What if someone is adding an image to the template outside of the_content() and the_post_thumbnail()? They could also obtain an image via wp_get_attachment_image() directly. Since that function applies the wp_lazy_loading_enabled filter, perhaps the filter should increment the counter instead of in the post_thumbnail_html and wp_img_tag_add_loading_attr filters both?

Note: See TracTickets for help on using tickets.