9 August, 2021

Better Nextjs Responsive Image Breakpoints

The Image Candidates List

The Nextjs image component enables us to easily provide Image Optimisation for either locally stored media, or by using a loader, from the Dynamic Media services from Cloudinary or Imgix.

Responsive Images using 'srcset' enables us to pass a 'candidate list' to the User Agent (the browser) such that it can select one most appropriate for the circumstances. The candidate list typically provides a series of variants of the same image but in different dimensions (using a w descriptor to advice the User Agent of their widths) - the user agent then uses details such as the viewport width, and device pixel density to choose the best dimension (typically the next size above - this is determined by the browser developer).

When using next/image the series of image dimensions provided are managed in next.config.js and the defaults are :

    module.exports = {
      images: {
        deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048, 3840],
      },
    }

Looking at that final step, from 2048 to 3840 - this means that for most browsers (the logic has varied between user agents over), any viewport above 2048, such as 2100px wide, will request, and hence receive an image which is 3840 pixels wide!

The relatiship between the image width, and the number of KB is non-linear. There is loosely a relationship between the number of pixels and the number of KB (the compressive variability due to the visual makeup certainly makes this more complex in reality) but the increase in the totaly number of pixels is determined by width x height, hence if the aspect ration is consistent, the number of pixels increases in a power of 2 rule.

The KB delta in the jump from 3500px to 4000px will be niticable greater than from 500px to 1000px.

** need screen grab here **

The Responsive Image Breakpoint generator is a great tool from Cloudinary, which can help demonstrate

As a result of this research, we may to fill in some of those gaps in the image candidate list, especially at the larger dimension end:

deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048, 2400, 2800,3200 3840]

Why not create hundres of width variants for our image candidates? This comes down to CDN caching efficiencies. Lets image we encode 1000 different image widths - for each variation of device and browser width, we will now be able to get closer to serving almost the exaxct correct image size to fit the layout - However, there is also an increasing risk that it will be a cache miss, and hence we lose out on this crucial aspect of delivery performance.

Back to blog posts list