Rendered image dimensions don't seem to match sizes attribute?
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
-
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.
Best,
Tamara
1
Answers
-
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.
Richard
0 -
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 to640w
, 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 actualsizes
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?0 -
I've spotted that I should have been using
px
in mysizes
attribute. This has reduced the 440px image to 1200px returned.0 -
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,
-Danny
1