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

Select the smaller image size from the list of available sources #186

Closed
Tracked by #22
mitogh opened this issue Feb 22, 2022 · 4 comments · Fixed by #243
Closed
Tracked by #22

Select the smaller image size from the list of available sources #186

mitogh opened this issue Feb 22, 2022 · 4 comments · Fixed by #243
Assignees
Labels
[Plugin] Modern Image Formats Issues for the Modern Image Formats plugin (formerly WebP Uploads) [Type] Enhancement A suggestion for improvement of an existing feature

Comments

@mitogh
Copy link
Member

mitogh commented Feb 22, 2022

Context

Every image metadata would contain a sources property for every single size available. The property is an associative array where each key on the array represents a mime type and each value on the array would be an associative array with 2 properties on it, the file and filesize of each mime type. For instance, this would like the following data for the medium size

// slice of a metadata from an image  stored in `_wp_attachment_metadata`
array(
  // ...additional image sizes
  'medium'  => array (
    'file' => '7rMFIAVGlVg-240x300.jpeg'
    'width' => 240,
    'height' => 300,
    'mime-type' => 'image/jpeg',
    'sources' => array(
      'image/jpeg' => array(
        'file' => '7rMFIAVGlVg-240x300.jpeg',
        'filesize' => 3831,
      ),
      'image/webp' => array(
        'file' => '7rMFIAVGlVg-240x300.webp',
        'filesize' => 2016
      )
    ),
  )
/// ...additional image sizes
)

The size of each image is expressed in bytes as returned by the filesize function.

Feature Description

Based on the work from:

And considering the scenario where multiple mime-types coexists for the same image, load the image with the smaller size instead of a specific format. As there might be a case where a specific image compresses better in JPEG than WebP (or if another format is available like AVIF in those cases make sure that the image that is delivered to the client is the image with the smaller file size instead of defined image size.

Logic to deliver an image to the client

  • If sources are available
  • order sources by filesize
  • deliver the first one in the list if is supported otherwise move to the next one on the list until a supported format is found.
  • otherwise deliver the former image for the specified size.
@mitogh mitogh added [Type] Enhancement A suggestion for improvement of an existing feature [Focus] Images [Plugin] Modern Image Formats Issues for the Modern Image Formats plugin (formerly WebP Uploads) labels Feb 22, 2022
@eclarke1 eclarke1 added this to Backlog in [Focus] Images via automation Feb 22, 2022
@eclarke1 eclarke1 moved this from Backlog to To do in [Focus] Images Feb 28, 2022
@eclarke1 eclarke1 added the Needs Dev Anything that requires development (e.g. a pull request) label Feb 28, 2022
@eclarke1 eclarke1 removed the Needs Dev Anything that requires development (e.g. a pull request) label Mar 1, 2022
@mitogh
Copy link
Member Author

mitogh commented Mar 2, 2022

Background

The information can be found on the metadata of an image using wp_get_attachment_metadata or directly reading the meta key _wp_attachment_metadata.

All image sizes contain a new property, named sources, this property is an array where each key on the array represents a mime for the image created for that particular size and mime. Each mime is stored as an array with 2 keys:

  • file
  • filesize

For the full image size the property can be found at the root level of the metadata of the file:

See:

Suggested approach

Currently, the approach is to simply render if available a WebP image, (see #187 for more details), however, the intended approach with this ticket is to ensure the smaller image size is delivered regardless of the mime type. Having a general approach to deliver the smaller image size regardless of the mime type gives room for growth as the logic would ensure only the smaller image size is delivered to the client (the browser). So in the case where a new mime type is added as part of the supported mime types or in the event where a JPEG is smaller in size than a WebP then that file would be served.

Note: One important note when comparing the images is to ensure that images, where the file size does not exist or is set to zero, due zero, is the default values when the file size can't be determined is skipped from the comparison, in that situation a logic should be added in order to either skip into a format with a file size available or if no other size available use this file as the last resource. As if we compare any filesize to zero as a number the smaller always would be a file where the filesize was not set.

When rendering an image size, order the images from the smallest file size to the highest one, considering the use case when a filesize has a zero or not set value in that instance:

  1. Consider the 0 as PHP_INT_MAX
  2. Return the first items on the mime types, given that the order was done in an ascending ordering in filesize.

This logic should be added in place only when rendering the content and replacing the images see:

@felixarntz
Copy link
Member

@mitogh Overall your suggestion from above sounds reasonable to me. Since this indeed ties in deeply with #187 though, we should first make a decision on that one as well before proceeding with a PR.

I just suggested an alternative filter in #187 (comment) which focuses on the valid image formats for the frontend rather than just enforcing a single one. That would allow developers to choose one or more formats they are okay with using in the frontend, and then the logic proposed above could decide which one to actually use.

@bethanylang bethanylang moved this from To do to In progress in [Focus] Images Mar 9, 2022
@bethanylang bethanylang moved this from In progress to To do in [Focus] Images Mar 9, 2022
@bethanylang bethanylang moved this from To do to In progress in [Focus] Images Mar 9, 2022
@bethanylang
Copy link
Contributor

@jjgrainger Noting per our discussion that this is ready to move ahead with engineering; let @felixarntz and @mitogh know if you have any questions on approach. Thanks!

@felixarntz
Copy link
Member

@jjgrainger @mitogh I have a potential concern with the implementation there. It feels like a neat idea to use the existing filter, but the problem with that is that it now universally prefers one MIME type over the other per attachment, which may not be the best solution. Let me clarify:

  • The current implementation only looks at the full image and decides based on that which MIME type should be preferred.
  • But what if e.g. for most image sizes (including full) the WebP image is smaller, but for e.g. thumbnail the JPEG image is smaller? The current implementation would still always use WebP in that scenario, but it would be better to use JPEG for the thumbnail size.
  • So I'm thinking maybe we need to enhance this to more deeply integrate into the replacement logic, per image size, rather than the overall MIME types filter.

Let me know what you think about that, if you agree, let's open a follow-up issue for this enhancement.

Regardless of that though, I think we should make this feature opt-in. Not because it's experimental or anything, but simply because it's not part of the core implementation, so it's somewhat an additional thing. The WP core implementation proposal as of now doesn't include storing and using the file sizes, so as long as that's the case I think this behavior in the plugin should be opt-in. I've opened #286 for that, with PR #287 ready for review.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Plugin] Modern Image Formats Issues for the Modern Image Formats plugin (formerly WebP Uploads) [Type] Enhancement A suggestion for improvement of an existing feature
Projects
No open projects
5 participants