Core SDK Libraries: Customize Your Generated srcset

Header image

Earlier this year, the imgix SDK team rolled out a new feature across all core libraries to help users build responsive images more easily: automatic srcset generation. However, this functionality only allowed users to generate one of two default srcset attributes: one for fluid-width1 images and one for fixed-width2 images. Although we were confident that these default srcsets would fit a majority of use cases, we thought the developer experience was a bit lacking. This motivated us to expand the SDK srcset-building interface to provide more flexibility in how srcsets are generated.

Automatically Generating Fluid-Width srcset

Original Default Behavior

Recall from our previous post that the srcset builder can be invoked in the following way:

// using imgix-core-js (https://github.com/imgix/imgix-core-js)
var srcset = new ImgixClient({
  domain: 'test.imgix.net',
}).buildSrcSet('image.jpg');

This produces the following fluid-width srcset attribute with 31 entries (truncated for brevity):

https://test.imgix.net/image.jpg?w=100 100w,
https://test.imgix.net/image.jpg?w=116 116w,
                    ...
https://test.imgix.net/image.jpg?w=7400 7400w,
https://test.imgix.net/image.jpg?w=8192 8192w

You may be thinking, 31 potential image variants is a lot to be serving. But not to worry—imgix includes unlimited derivatives, so having this many srcset entries won’t run up your monthly bill. With that in mind, this is great default behavior since it produces an image that serves many sizes, right out of the box.

However, not everyone may want these default widths or to even potentially serve an image as large as 8192px. So while we believe most imgix users will see immediate gains with the default output (assuming proper use of sizes), we want to enable users to have more say via configuration.

With the latest updates, you can now customize srcsets in five new ways:

  • Assigning a width range (via minWidth and maxWidth), to specify the minimum and maximum image widths that appear in the generated srcset
  • Assigning a width tolerance to specify the maximum tolerated size difference between an image's downloaded size and its rendered size
  • Assigning a specific array of widths directly
  • Disabling variable output quality
  • Overriding the output quality entirely

In this post we’ll go through what each of the above features does, why you might want to customize it, and how to specify these configurations using the improved interface.

Customizing Width Range

The new width range option allows developers to specify a minimum and maximum width for the srcset. Doing so ensures that widths begin and end at specified values. For example, to create a srcset with widths between 320px and 880px, set the following minWidth and maxWidth values:

var srcset = new ImgixClient({
  domain: 'test.imgix.net'
}).buildSrcSet(
  'image.jpg', 
  {}, // add no imgix parameters
  { minWidth: 320, maxWidth: 880 } // specify a minimum and maximum widths
);

This will produce the following srcset:

https://test.imgix.net/image.jpg?w=320 320w,
https://test.imgix.net/image.jpg?w=372 372w,
https://test.imgix.net/image.jpg?w=430 430w,
https://test.imgix.net/image.jpg?w=500 500w,
https://test.imgix.net/image.jpg?w=580 580w,
https://test.imgix.net/image.jpg?w=672 672w,
https://test.imgix.net/image.jpg?w=780 780w,
https://test.imgix.net/image.jpg?w=880 880w

Customizing Width Tolerance

The new widthTolerance modifier allows developers to specify the maximum allowable width tolerance between downloaded and rendered images:

var srcset = new ImgixClient({
  domain: 'test.imgix.net'
}).buildSrcSet(
    'image.jpg',
    {}, // add no imgix parameters
    {
        minWidth: 320,
        maxWidth: 880,
        widthTolerance: .20
    } // assign a width tolerance of 20% and a min/max width
);

Which returns the following:

https://test.imgix.net/image.jpg?w=320 320w,
https://test.imgix.net/image.jpg?w=448 448w,
https://test.imgix.net/image.jpg?w=628 628w,
https://test.imgix.net/image.jpg?w=878 878w,
https://test.imgix.net/image.jpg?w=880 880w

By setting the width tolerance to .20 (or 20%), we can fine-tune our srcset further. Here we have increased the allowable tolerance between the size of the requested image and that which gets rendered on the browser. In essence, this results in fewer image entries in our attribute compared to the default behavior.

The width tolerance modifier allows users to slide the scale between two choices: maximizing cache hits or minimizing the size difference between the downloaded and rendered image. Specifying a larger width tolerance (as in our previous example) will maximize cache hits but can come at the expense of image quality due to sizing-up images to fit their container. Conversely, specifying a smaller width tolerance means end users are more likely getting the correctly sized image, but decreases their chances of hitting the CDN cache.

Note that the range specified by minWidth and maxWidth results in a closed interval (both left- and right-inclusive); i.e. the above srcset still begins and ends on our minimum and maximum widths—only the “spacing” or width tolerance has changed.

Specifying Image Widths

Now let’s say that these srcset width-values are really close to, but not exactly, the values we want. If a user knows the exact desired image widths, they are able to specify them using widths:

var srcset = new ImgixClient({
  domain: 'test.imgix.net'
}).buildSrcSet(
    'image.jpg',
    {}, // add no imgix parameters
    { widths: [320, 448, 572, 600, 647, 878] } // assign widths directly
);

Which returns the following:

https://test.imgix.net/image.jpg?w=320 320w,
https://test.imgix.net/image.jpg?w=448 448w,
https://test.imgix.net/image.jpg?w=572 572w,
https://test.imgix.net/image.jpg?w=600 600w,
https://test.imgix.net/image.jpg?w=647 647w,
https://test.imgix.net/image.jpg?w=878 878w

Auto-Generating Fixed-Width srcset

Original Default Behavior

Prior to this update, we could create a fixed-width srcset like so:

var srcset = new ImgixClient({
  domain: 'test.imgix.net',
}).buildSrcSet(
  'image.jpg',
  { w: 330 } // specify a width = 330
);

Recall from our last post that by supplying certain dimensional rendering parameters (width w or height h and aspect ratio ar together), we output a fixed-width srcset instead:

https://test.imgix.net/image.jpg?w=330&dpr=1&q=75 1x,
https://test.imgix.net/image.jpg?w=330&dpr=2&q=50 2x,
https://test.imgix.net/image.jpg?w=330&dpr=3&q=35 3x,
https://test.imgix.net/image.jpg?w=330&dpr=4&q=23 4x,
https://test.imgix.net/image.jpg?w=330&dpr=5&q=20 5x

In the above example, we can see that the quality q decreases as device pixel ratio dpr increases. Reducing the quality allows you to serve a lighter image with nearly no perceivable difference in image quality. This is a small optimization that our SDK provide out of the box.

However, if file size is not an issue or if there’s a dpr-to-quality ratio that better suits your needs, you can now override or disable the variable quality all together:

To disable variable quality, we can set disableVariableQuality to true:

var srcset = new ImgixClient({
  domain: 'demo.imgix.net'
}).buildSrcSet(
    'image.jpg',
    { w: 330 },
    { disableVariableQuality: true } // disable variable quality
);

The result is a srcset in which the qualities have been removed, explicitly. Note that disabling variable quality results in a default quality of q=75 being applied, implicitly.

https://demo.imgix.net/image.jpg?w=330&dpr=1 1x,
https://demo.imgix.net/image.jpg?w=330&dpr=2 2x,
https://demo.imgix.net/image.jpg?w=330&dpr=3 3x,
https://demo.imgix.net/image.jpg?w=330&dpr=4 4x,
https://demo.imgix.net/image.jpg?w=330&dpr=5 5x

If neither variable quality nor a constant quality of 75 suits your needs, you can also assign a custom quality. This quality can be any number between 0 and 100.

var srcset = new ImgixClient({
  domain: 'demo.imgix.net'
}).buildSrcSet(
  'image.jpg',
  { w: 330, q: 100 } // override the default variable quality
);
https://demo.imgix.net/image.jpg?w=330&q=100&dpr=1 1x,
https://demo.imgix.net/image.jpg?w=330&q=100&dpr=2 2x,
https://demo.imgix.net/image.jpg?w=330&q=100&dpr=3 3x,
https://demo.imgix.net/image.jpg?w=330&q=100&dpr=4 4x,
https://demo.imgix.net/image.jpg?w=330&q=100&dpr=5 5x

Summary

In this post, we went through the different ways users can fine-tune the srcset returned by our core libraries. We hope to not only provide powerful utilities to help users build images more quickly, but also allow them the flexibility to do so in the way that they want.

Have any suggestions or questions about the developer experience in our libraries? Feel free to open an issue on GitHub or contact us via our support line.

  • 1Fluid-Width srcset: attributes contain image candidate strings (URLs) whose widths vary. This kind of srcset is useful when the goal is to serve an image at different sizes based on the browser's viewport.
  • 2Fixed-Width srcset: attributes contain image candidate strings (URLs) whose widths are fixed, but resolution (pixel density) varies. This kind of srcset is useful when the goal is to serve the same size image, across different devices, at different resolutions (pixel density).

Stay up to date with our blog for the latest imgix news, features, and posts.