Improving Your Image Performance with Cosmic and imgix
Thomas Dale is the Head of Account Management for imgix, a powerful real-time image processing and CDN delivery solution. Thomas works with imgix customers and partners to power partnerships, integrations and implementation of the fantastic imgix service.
Cosmic + imgix
All of the images you upload to Cosmic are already transformed to imgix URLs, a powerful real-time image processing and CDN delivery solution. This article will help you take advantage of many of the included features of imgix which include optimizing image formats, compressing, intelligently cropping, and so much more!
Where are my imgix URLs?
Every image you upload to Cosmic is already converted to a imgix URL! Here is a screenshot of the image metafields section in an object:
You can see that the URL is already an imgix URL! The way you modify an imgix URL is by simply adding a query string following the path. Typically an image's path ends in the format of the image, for example: ".jpg". You would simply add a question mark and then begin entering the query string to modify the image.
In the example above, "w=600" will size the image to a width of 600 pixels and "exp=1" will set the exposure setting to 1. It is important to add an "&" in between each of the parameters in the query string. You can see a complete list of the imgix API that you can enter as a query string here: https://docs.imgix.com/apis/url.
Most Common imgix Features
You will notice that our docs contain a lot of different parameters! So I'm going to try and tell you about a few awesome features to get you started. The first is the auto parameter. I like adding auto=format, compress to all of my URLs. This will have the image change its format based on several factors:
- If the browser is Chrome, it will change the format to WEBP. This is a great format by Google that will make your images lighter and look better. It even supports transparency.
- If the browser is not Chrome, it will then determine if the image contains any transparent pixels. If the image does contain transparent pixels (like a logo perhaps?) it will change the format to a PNG8. This is a lighter version of PNG that supports transparency. If the image does not contain any transparent pixels it will change the format to progressive JPEG. This is supported by all modern browsers, is ~ 10% lighter than a JPEG, and it loads the image by making it slightly blurred then filling in the image (although this happens extremely quick and can be hard to notice).
Just using the auto=format, compress to change formats is already going to have a humongous impact on your image performance. This same API does do a few additional items as well. It will strip the color space from the image, which is about 3 KB. This is no longer needed with modern browsers so it is smart to remove this. Finally, it will compress the quality of the image. If you use this parameter and you feel that the image's quality is being compressed too much, you can certainly modify this as well. The way to counter this quality reduction is to add an additional API to the query string identifying what quality level you want. Although the quality number goes from 1-100, please don't think of the quality levels as a %. It is simply a number on a scale and each digit is not equal. For example, q=40 is not half the quality of q=80. The default is actually q=75, so that is often a good number to use.
Here is an example URL with all of these together:
You can see the name of the image is vista.png, because it was originally a PNG. There wasn't transparency in this image. When you open this in Chrome, it will be a WEBP. When you open this in another browser like Safari, it will be a progressive JPEG.
width, height, & crop
One of the most needed functionalities of an image processing solution is to be able to resize the height and width of an image. A common mistake with websites is using only css to size your images. This will make your image or container the correct size when viewing on your website, but the image being loaded may be a much larger image. If you were to inspect an image with your browser's dev tools, it will often show the size the image is viewed and the actual size of the loaded image:
This image is viewed as a smaller thumbnail that is 168 pixels wide by 112 pixels tall. It is actually loading a 3008 wide by 2000 pixel tall image! But I can modify this URL from https://cosmic-s3.imgix.net/112a4440-7857-11e7-998b-6dbc6e078b76-will-langenberg-8989.jpg (which is 1.1 MB) to include auto=format,compress (my favorite combo!) and then add a w=200 to lower the width of the image. You will notice that I also added a dpr=2; this will set the device pixel ratio to 2, which essentially doubles the width but will improve the look of smaller thumbnails in mobile devices.
With these changes, the image is now 16.1 KB (or 15.4 KB in a Chrome browser): https://cosmic-s3.imgix.net/112a4440-7857-11e7-998b-6dbc6e078b76-will-langenberg-8989.jpg?auto=format,compress&w=200&dpr=2
A note on cropping. You will notice that I entered a w=200 and I did not enter a height. By default, imgix will respect the current aspect ratio of the image and set the height appropriately. If you did want a square, you could set a w=200&h=200&fit=crop. This would create a square and crop to the center of the image. There are many other ways to choose how to crop, such as cropping to faces, objects, or focal points. If you want to use one of these methods, I would look at them in the imgix API docs: https://docs.imgix.com/apis/url/size/crop.
Implementing imgix Changes Across Your Whole App
Taking these changes in mind, I wanted to apply them to a pre-existing app in Cosmic, the Vue.js Photo Gallery. In this app, there is the large gallery image which is displayed as a background image URL and small thumbnail images displayed in an img tag. I forked the Github article for this and added auto=format, compress to all of the images.
In the screenshot above you can see the changes I made to the larger gallery images. Since this is a nested string I simply added the imgix string after the imgix_url in the v-bind. For this example, I added a width of 2000 and a quality of 75. This will leave these images at a good quality and size them as a large image. I will be loading my largest original images to this app and I can be sure they will be sized at a correct size for a large gallery image.
In the screenshot above you can see the changes I made to the thumbnail images. For this example I had to add an additional function I titled decorateImgixUrl which returns the imgixUrl and appends the imgix API string to the end. For the thumbnail images I added a width of 200 and a dpr setting of 2. This now resizes the same large image I had uploaded down to 200 width, and the addition of the dpr setting will help to improve the visual quality of these thumbnails in a mobile view.
This is all a pretty simple change, just adding the automatic features as well as resizing, but the effect it had on the demo example for this site was astounding! Originally, this page weighed 3.1 MB but now it only weighs 645 KB! If you already use the Vue.js photo gallery app, this change has been applied to this app so you can update this easily yourself!
Hopefully this brief demonstration shows you how much of an impact using just a few of imgix's popular features can have on your websites. I encourage you to look through the imgix API docs and see what other features are available for you to use.
New dashboard private beta and API v3 release
January 31, 2023
Add a headless CMS to Astro in 3 easy steps
September 20, 2022