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

Module Proposal: auto-sizes for lazy-loaded images #791

Closed
joemcgill opened this issue Jul 25, 2023 · 6 comments · Fixed by #904
Closed

Module Proposal: auto-sizes for lazy-loaded images #791

joemcgill opened this issue Jul 25, 2023 · 6 comments · Fixed by #904
Labels
[Focus] Images Issues related to the Images focus area [Type] (Legacy) Module Proposal A new module proposal (legacy)

Comments

@joemcgill
Copy link
Member

Overview

  • Image Auto-sizes
  • Proposed module slug: image-auto-sizes
  • Proposed module owner GitHub username(s): @joemcgill (others welcome!)

About the module

Recently, the HTML spec was updated to support sizes="auto" for lazy-loaded images. The purpose of this module would be to automatically add auto to the beginning of the sizes attribute for any image that is being lazy loaded.

Purpose

While implementation is still ongoing, this could be a pretty big performance improvement for WordPress sites, since many rely on the default sizes attribute rather than filtering the value to a more accurate one based on the intended layout of the site's theme.

Scope

This would only implement auto sizes for lazy-loaded images as an experiment until browser adoption for this feature is far enough along to propose for core, and should be a base implementation that a future core proposal would be based on.

This does not take the place of #760, which would still be useful to pursue, but could make that effort less important by getting the same performance benefits for all lazy-loaded images.

At minimum, the implementation should filter wp_calculate_image_sizes to prepend "auto, " to the beginning of the string. Given that this is a progressive enhancement, any browser that doesn't recognize the "auto" value in the sizes string, will ignore it and process the rest of the string like normal.

It is currently unclear if this syntax is used on an image that is not being lazy loaded, if the original sizes value will be respected or if the default 100vw fallback for the parser will be used instead, so experimentation against a real implementation will be important. If the default is used, then the filter would need to also check to see if lazy loading is enabled and likely post-filter images to remove auto sizing for any images not being lazy loaded, since srcset and sizes is calculated prior to lazy loading in wp_filter_content_tags.

Rationale

See above.

Other

Additional info:

@joemcgill joemcgill added the [Type] (Legacy) Module Proposal A new module proposal (legacy) label Jul 25, 2023
@joemcgill joemcgill changed the title Module Proposal: auto-sizes for images Module Proposal: auto-sizes for lazy-loaded images Jul 25, 2023
@felixarntz
Copy link
Member

Thanks @joemcgill, I really like this idea, and I agree the PL plugin would be the perfect avenue to get started on this, given its browser spec is so bleeding edge and still in motion.

Do you have any information on browser support? I see the spec is moving, but I'd want to make sure it's supported by at least one major browser before adding it in a plugin.

@khoipro
Copy link

khoipro commented Aug 2, 2023

I have played sometimes with lazysize.js and found sometimes adding sizes="auto" will load incorrect image sizes. We will need to investigate this case carefully.

The case in this PR seems only work if we add loading="lazy, while the Page Speed checking tool will leverage the first image (on the first screen) should be no lazyload.

@mukeshpanchal27
Copy link
Member

@joemcgill, Thank you for the proposal! I must say, I really like the idea, and I am happy to support you in any way I can.

@eclarke1 eclarke1 added the [Focus] Images Issues related to the Images focus area label Sep 4, 2023
@joemcgill
Copy link
Member Author

Looks like the auto-sizes implementation is moving forward with implementation in Chromium starting. I'm thinking we might want to prioritize some early explorations for supporting this in early 2024 cc: @felixarntz, @adamsilverstein

@joemcgill
Copy link
Member Author

joemcgill commented Dec 14, 2023

The new auto-sizes feature has now landed in Chromium 🎉

I put together a quick demo that can be used for observing how the feature is working in supporting browsers (e.g., Chrome Canary) and existing browsers.

Examples

For each of the examples, I've use a 960px image with a srcset list that provides sizes at 960, 800, 400, and 200 pixel widths. I've constrained the container they are in with CSS that has a max-width of 400px. For each example, the assumption is that the browser will base resource selection on a value that is equivalent to the naturalWidth property of the image. For debugging purposes, I'm displaying the viewport width (i.e., window.innerWidth) and display density of the device (i.e., window.devicePixelRatio) along with the relevant properties of each image.

For each of the following cases, I'm also reporting the naturalWidth values based on viewport widths that are larger than 960px.

Control – the current WP default: sizes="(max-width: 960px) 100vw, 960px"

  • w/ support – naturalWidth: 960px
  • w/o support - naturalWidth: 960px

Auto sizes w/ lazy-loading: sizes="auto" loading="lazy"

  • w/ support – naturalWidth: 400px (this is accurate) 🟢
  • w/o support - naturalWidth: 100vw (sizes is invalid, so the browser is using the default value) 🔴

Auto sizes w/o lazy-loading: sizes="auto"

  • w/ support – naturalWidth: 100vw (without lazy-loading, auto cannot be used, so the browser uses the default value) 🔴
  • w/o support - naturalWidth: 100vw (auto can't be applied w/o lazy loading, so the browser is using the default value) 🔴

Auto sizes + fallbacks w/ lazy-loading: sizes="auto, (max-width: 960px) 100vw, 960px" loading="lazy"

  • w/ support – naturalWidth: 400px (auto is used, this is accurate) 🟢
  • w/o support - naturalWidth: 960px (auto is skipped, and value is used)

Auto sizes + fallbacks w/o lazy-loading: sizes="auto, (max-width: 960px) 100vw, 960px"

  • w/ support – naturalWidth: 100vw (auto can't be applied w/o lazy loading, so the browser is using the default value) 🔴
  • w/o support - naturalWidth: 960px (auto is skipped, and value is used)

Key
🔴 – Calculation is worse
🟢 – Calculation is improved

Conclusion

Currently, it looks like we can apply auto sizes with a fallback (e.g., auto, (max-width: 960px) 100vw, 960px) only when an image has loading="lazy" applied in order to ensure we're not causing a regression for either supporting or non-supporting browsers. This is expected, but it's nice to see this confirmed by the test cases. An initial implementation will need to be able to account for whether an image has lazy loading applied prior to prepending auto to the sizes value.

joemcgill added a commit that referenced this issue Dec 14, 2023
This adds a new module that will automatically enhance the `sizes` attribute of lazy-loaded images to support the new `auto` syntax.

See: whatwg/html#4654

Fixes: #791.
@felixarntz
Copy link
Member

This can be considered fixed by #904 and the relevant follow up PRs. Any further development to the plugin can happen against feature/modules-to-plugins for now. Once that branch is merged into trunk, development should happen against trunk.

For reference, the plugin is already published here: https://wordpress.org/plugins/auto-sizes/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Focus] Images Issues related to the Images focus area [Type] (Legacy) Module Proposal A new module proposal (legacy)
Projects
Development

Successfully merging a pull request may close this issue.

5 participants