Images are one of the most widely used assets on the web and with all the right reasons, but they may cause a slow loading time of your website if not included in the right way. There are a lot of things you have to consider while preparing images for the web, and in this post we’ll take a look at what those things are and how Drupal 8 can help you make this process automatic.
First of all, let’s look at what makes an image optimized for the web. Web as a media is in fact a lot simpler in quality demand opposed to print media but it does have its own specialties. The biggest challenge here is to get the best possible image quality with the smallest possible file size by adjusting image dimensions and quality while also being able to serve each screen type and size just the right image. This may seem a bit overwhelming at first, but keep reading because in this post I’m going to show you how to achieve that step by step using Drupal 8 core features.
Adjusting Image Dimensions
Out of the box, Drupal offers a really great tool for optimizing images called Image styles. In general, image styles are used to control the size of displayed images, although you can also do other cool stuff with them, such as making images black and white. Drupal allows us to set different image styles which we can then use in different areas of the page.
For example, an Article content type can use a bigger image for a detail page and a smaller one for a teaser display, usually used in the Articles list page. The great thing about image styles is that you only need to set them once and it will automatically display the right image size every time, no matter what the size of the originally uploaded image is.
An image style can be set in the ‘Manage display’ section of the content type setup. By clicking on the gear icon on the image field, the setting will be shown where you can assign any of the previously configured image styles to this field. If the image style you wish to assign is not available, you can create a new one by clicking on the ‘Configure Image Styles’ next to the image style dropdown.
This will take you to the Image Styles configuration page. Click on the ‘Add image style’ button. First of all, you’ll have to give a name to the new image style. You can choose whichever name you would like but it is recommended that you add image dimensions to it.
After the name is set up, you can add different effects to the image style. A few effect options are given, but for our purposes, the two most important ones are:
- Scale: this effect allows you to only specify the width or height of an image, and the one that is not given will be automatically set to keep the original image ratio.
- Scale and crop: this effect scales an image, but it also crops it so that it always fits the given ratio.
Choose the effect you want for your image style, set the properties and save it. In the example below, I chose Scale effect and only specified a width of 970px (based on the design, I calculated that the image using this image style will never be wider than 970px), letting the height adjust to the original image ratio.
Now the only thing left to do is to assign the new image style to the image field. Go back to the ‘Manage Display’ section of your content type setup, click on the gear icon, choose the new image style and hit save.
To see how much effect image styles have on the actual file size and loading time, we need to do some testing. First of all, let’s see what happens when no image style is assigned to the image. For this example, I used an image with an original file size of 6.7MB, meaning it is way too big to be used on our website because it took 2.08s for this image to load.
The second test I ran is with image style assigned to the image. The results show great improvement of the file size, as well as loading time, because, using the same original image, the file size is now 956KB and it loads in only 487ms.
This is all very exciting - but there’s one more question that needs to be answered: did we sacrifice any of the quality to achieve this result?
Click on the image to enlarge
I took a screenshot of an image without image style (on the left side) and compared it to the screenshot of an image with image style (on the right side). I noticed that the quality is a bit lower on the scaled image.
The root of this problem, however, is not the image style per se. These tests and screenshots were taken on a MacBook Pro which has a retina display, meaning that one actual pixel of an image is seen as half of a pixel on this device, and this is why the image got upscaled, making it look a bit blurry. To test it out, I created a new image style that is twice as big (Image Scale 1940 x ...). Now we can see that the image using the new image style looks just as sharp as the original one.
Click on the image to enlarge
This, however, opens up a new question for us. Which image should we use? The first one is smaller and looks great on normal displays but makes images a bit blurry on retina displays. The second one, on the other hand, looks great on all devices but is bigger than the first one. Luckily Drupal 8 has another tool that will help us get out of this dilemma, but before we take a look at what it is and how it works, let’s try to optimize those images of ours a bit more.
Defining Image Quality
In the first part, we took care of adjusting the image size; but there’s one more thing we can control in order to get the file size smaller - adjust the image quality. Drupal 8 has a perfect tool for that and it is very simple to use.
All we have to do is go to the Admin > Configuration > Media > Image toolkit.
Here we can adjust the quality of the image. The best results are given if the number is between 60 and 80. In the example below, I set the number to 75. In order to see the changes on the previously uploaded pictures, we need to delete all ‘styles’ folder content in the Drupal directory. There are three different ways of doing that and you can choose the one that works best for you:
- Through the interface: you can Flush each image style separately by going to Configuration > Media > Image styles and choose ‘Flush’ action from the Operation column.
With drush command: drush image-flush. You will also be given an option to choose which style you want to flush.
Deleting folders manually in your website directory: folders that need to be deleted are located in ‘sites/default/files/styles’ folder. Delete everything in there but leave the styles folder.
After that go to your Drupal site and clear cache (Configuration > Development > Performance). When the page reloads, all images that you have uploaded before will be regenerated and they will all have the specified image quality.
Now we’re ready to run some tests and see how much of an impact this has on the file size. The first test I ran was using the image style for retina (1940 x …). Before that, the image file size was 3.2MB.
This time around we can see that the file size dropped to 383KB which is a great improvement. Even better are the end results for the image using the smaller image style. Let’s take a look at this one as well. Remember that previously the file size of this image was 956KB.
This time the file size is only 126KB and it loads in 35ms. The result is impressive but let’s see what this did to the actual image quality. Let’s keep in mind that these tests are run on MacBook Pro that has a retina display and therefore images need to be twice as big to be displayed as they would have to be on a regular screen.
Click on the image to enlarge
With the image quality set to 75 we can now really see the difference in the smaller image style. This image would look great on normal displays and the file size is just right but the image still doesn’t look so good on the retina screen. Using the bigger image style, however, we get a better result in the said case.
Click on the image to enlarge
The file size is now 383KB and the look is almost identical to the original image. Now we can say that images have the optimal file size if we compare them to the actual quality, but one problem still remains - we have two image styles, each one optimal for a different screen type.
Nowadays we have to consider many things when we’re making a website and amongst them, different screen types and sizes are one of the most important ones. Responsive design has become a standard in today's web development practice and images are no exception. We don’t really need an image that is 970px wide on a mobile screen that is 500px wide, but we do need an image that is 1970px wide on a retina display of a screen that is 1000px wide.
As we can see in the examples above, it really does matter what we serve to what screen - and no, we do not need to load the biggest image on all screens so that the image would look nice and sharp. This would increase the loading time of our website and that is also something we don’t want. What we do need to do is play it smart - serve every screen type and size exactly what it needs to display an image in its best light. Again, lucky for us, Drupal 8 has just the right tool for that and that tool is called Responsive images.
Responsive images are a Drupal 8 core module, meaning that Drupal 8 already comes with it, all you have to do to use it is enable it. To do that, go to Admin > Extend, then search for the module and enable it. We have already talked about how to use this module in this blog post, so I will not go into too much detail here. I will, however, explain how to solve the dilemma with retina displays that we have previously encountered.
Following the instructions in the link above you should be able to change image styles (sizes) or even the entire image depending on the screen size - for example, a mobile display can use a different, smaller image than a laptop display.
This module, however, also lets us set a different image style according to the retina display value. There is one requirement though - the theme you are using needs to have those multipliers values defined in theme.breakpoints.yml file. If the multiplier of 2x is defined for each breakpoint, then you will see it in the backend as an option to which you can assign an image style to.
Here you can assign a retina image style for a specific breakpoint - making the image adjust to a screen size and display type. For the example above it would mean that on a laptop that is not retina, the browser would render an image with Image scale (970 x …) style, but on a laptop with retina display, it would render an image with Image scale (1940 x …), making it truly the optimal choice.
In case you’re wondering - there is no magic to it. This module uses a HTML5 picture tag to change the image src depending on the screen size and type. There is, however, a downside - some browsers, including IE, do not support this HTML5 tag which means you’ll have to use a picturefill solution.
In this post, we’ve taken quite a deep look into how to make image optimization automatic with Drupal 8 and how to successfully decrease an image file size from 6.7MB to as low as 126KB. If a website you’re building has a lot of images per page, then this optimizing process may lower the loading time, but it can still be above the average. If this is the case then I would advise some extra steps to solve the problem, and your best bet in this case would most definitely be to include lazy loading functionality to your website.