Rendered image dimensions don't seem to match sizes attribute?

richTC Member Posts: 4

Hi, I'm building a website using Next.js and serving images using Cloudinary. I am using the next/image component and can see the srcset of 16, 32, 48, 64, 96, 128, 256, 384, 640w... in my rendered image's attributes. I am using g_auto,f_auto,c_fill,w_XXX,q_auto:best.

I'd like to know why the returned intrinsic size doesn't seem to have much relevance to the requested size I enter in the sizes attribute? I'm entering a single value in the sizes attribute for testing purposes. For example:

sizes="12px" returns the 32w src; sizes="20px" returns 48w src; this carries on for all sizes, with the src changing at seemingly unrelated breakpoints. I thought I had found a pattern for the breakpoints between src 's, where the Retina (2x width) goes from being closer to the size below, to closer to the size above. But this pattern breaks at the 256w src.

I've included my test spreadsheet showing requested sizes, returned sizes and my guess for the pattern.

How can I predict which size will be served? This is causing my site to load much larger filesizes than needed, and page speed and performance scores to drop.

Thanks, Richard


Best Answer

  • Tamara
    Tamara Member, Cloudinary Staff Posts: 74
    Answer ✓

    Hi @richTC,

    The behavior you're observing is related to how browsers interpret the `srcset` and `sizes` attributes in conjunction with our image transformations. The `srcset` attribute in an image tag provides the browser with a list of different image sources, each with a specified width. The `sizes` attribute, on the other hand, indicates the layout size of the image in CSS pixels as a hint to the browser to decide which image source to use.

    When you specify a value in the `sizes` attribute, the browser selects the most appropriate source file based on the current layout size (viewport) and the screen density. The browser doesn't necessarily choose the image that matches the exact number of pixels specified in the `sizes` attribute. Instead, it tries to find a balance between the image file size and the display quality.

    The breakpoints at which the browser decides to switch to a different image source are not determined by us, but by the browser's own internal logic. This logic can vary between different browsers and is designed to optimize the trade-off between image quality and bandwidth usage.

    If you're seeing unexpected results, it might be worth experimenting with different values in the `sizes` attribute, or adjusting the transformation parameters to better suit your specific needs.




  • richTC
    richTC Member Posts: 4

    Thanks Tamara,

    That's useful to know that there's not really anything I can do about it, and I probably have to adjust the parameters rather than the dimensions to get a smaller filesize.


  • Fahadjutt
    Fahadjutt Member Posts: 1

    The inconsistency you're observing in the relationship between requested sizes and returned sizes with Cloudinary's Next.js integration might be due to various factors, including the automatic responsive behavior of the next/image component. To ensure more precise control, consider specifying the exact width using the width attribute instead of relying solely on the sizes attribute. Adjust the width attribute according to your design requirements for consistent results.

  • richTC
    richTC Member Posts: 4
    edited February 1

    Hi @Tamara and @Fahadjutt

    Thanks for your suggestions. I have managed to reduce the filesize being delivered by using the q attribute but I am still being given enormous image dimensions for the actual size on screen. It really seems like something isn't working correctly.

    For example, I have an image that is 440x603 on screen, and I've given the NextImage component a width and height to match. (This won't work in reality as the image needs to be responsive to the content alongside it, but that's a different problem).

    `<NextImage media={image} width={440} height={650} sizes="640w" fill={false} />`

    I have set the attributes in my Cloudinary loader to g_auto,f_auto,c_auto,q_auto:eco.

    I have hard-coded the sizes attribute to 640w, which is too small but I am trying to force a smaller image to be returned.

    Chrome loads the largest possible image in the srcset, 3840px wide at 384kb. The same happens if I try to have an actual sizes attribute with different options. I'm sure I must be doing something wrong? This can't be the default behaviour of next/image and the browser?

  • richTC
    richTC Member Posts: 4

    I've spotted that I should have been using px in my sizes attribute. This has reduced the 440px image to 1200px returned.

  • DannyFromCloudinary
    DannyFromCloudinary Member, Cloudinary Staff Posts: 80

    Hi @richTC .

    Thanks for the update. I've had a look at the official Next docs for the sizes attribute and it seems that it uses the same syntax as CSS media queries, so you will need to use px, vw, etc as required.

    Is there anything else we can help with?

    Kind regards,