I'm trying to fill a fixed-size container with an image. layout="fill"
works like a charm, but even though container is only 125x125
, the original image gets downloaded that has a resolution much higher than that and hence weights much more. I'm able to get reduced resolution with layout="fixed"
, but I lose the "fill" behaviour this way.
Is there a way to take the best of those 2 worlds with next/image
- fill parent container, and at the same time reduce the size of files downloaded to client device?
CodePudding user response:
You can configure the deviceSizes
property in next.config.js
to match the breakpoints used in your app, as those are used to generate the next/image
's srcset
s, and serve the correctly sized image.
If you know the expected device widths of your users, you can specify a list of device width breakpoints using the
deviceSizes
property innext.config.js
. These widths are used when thenext/image
component useslayout="responsive"
orlayout="fill"
to ensure the correct image is served for user's device.
The above should be paired with the sizes
attribute on the next/image
if the rendered image takes up less than the full viewport width.
If you are using
layout="fill"
,layout="responsive"
, orlayout="raw"
it's important to assignsizes
for any image that takes up less than the full viewport width.For example, when the parent element will constrain the image to always be less than half the viewport width, use
sizes="50vw"
. Withoutsizes
, the image will be sent at twice the necessary resolution, decreasing performance.
As an example, let's assume your app uses the following device breakpoints [320, 640, 1024, 1280, 1920]
, and you're rendering a 240x240
image.
Update the deviceSizes
property to match the breakpoints:
// next.config.js
module.exports = {
images: {
deviceSizes: [320, 640, 1024, 1280, 1920],
// Other existing `images` configs
},
// Other existing configs
}
Then set the sizes
property on the next/image
to suggest the ideal image size.
<div style={{ position: 'relative', width: 240, height: 240 }}>
<Image
src="<image-url>"
layout="fill"
sizes="50vw"
/>
</div>
You should adjust the above values to better fit your use case.