On this page
  1. Optimize your images
  2. Responsive images with srcset and sizes
  3. Lazy loading images
    1. Benefits of lazy loading
  4. Preload the image
  5. Priority Hints - fetchpriority (experimental technology)
  6. Use browser cache
  7. Use image-set() for the background images
  8. Use a CDN - content delivery network
  9. Inline svg element replaced with image element
Catching picture while driving fast on the road

8 tips to speed up image loading

Slow loading images impacts not only the user experience but also hurts your site's ranking in the search results. Find out how to improve loading images.

If your website uses quite a lot of images then this may impact the page loading speed as well as the page rendering.

A faster loading website means:

  • Better user experience.
  • Improving rankings on search engines since site speed is a ranking factor.
  • Potentially reducing the hosting cost, if you pay-as-you-go for the transfer data.

Let’s then explore the possibilities of image speed loading.

Optimize your images

This step should be fairly easy. Use the tool to optimize your images. One of the tools could be ImageOptim (Mac only) or pngquant or Squoosh. These tools will help you to optimize your images.

Note: while this type of optimization is usually safe, there are situations where size might be stored in the database and just overwriting the image (e.g. by uploading them directly through FTP) with a newly optimized version may bring an unexpected behavior.

Responsive images with srcset and sizes

Loading the same image for all viewport sizes impacts not only the loading speed but also the rendering. A single image that perfectly fits into large viewports doesn’t fit well into small viewports (e.g. mobile). If someone uses a small screen device on a low bandwidth network, they’ll download unnecessarily large images.

The srcset attribute and sizes can be used to inform the browser about different sizes of the same picture that you have created. Here is an example:

<img srcset="flower-480w.jpg 480w, flower-800w.jpg 800w" sizes="(max-width: 600px) 480px, 800px" src="flower-800w.jpg" alt="Beautiful rose flower"/>

The list of images we’ll give the browser to choose from and the sizes of each image are specified by the srcset attribute. A comma separates each set of image data from the one before it.

When specific media circumstances are met, sizes define a set of media conditions (such as screen widths) and suggest the appropriate image size to use.

Lazy loading images

Use the loading attribute to specify the urgency with which you want an image to load for the browser. Using loading="lazy" tells the browser to load the image only when it’s just about to be rendered in the viewport. In other words, images that aren’t displayed for the user won’t be fetched by the browser. Example:

<img src="example.png" alt="A description of the image." width="500" height="250" loading="lazy"/>

Benefits of lazy loading

  • Reduces initial load time – images that aren’t visible won’t be loaded therefore the page will load faster.
  • Saving bandwidth – images that aren’t visible won’t be downloaded therefore bandwidth won’t be used, specifically on limited data plans. In some cases, it may impact the bill you pay for CDN or hosting.
  • Improving page rendering – the browser won’t need to process images until they are requested by scrolling the page. That saves processing time, battery, and other system resources.
  • Good for SEO – speed loading is one of the most important factors that impacts the search ranking.

Preload the image

You can instruct the browser to preload crucial images in the document’s <head>.

<link rel="preload" href="example.png" as="image"/>

Note that the browser will have to lower the priority of another resource, like a script or font file, when you ask it to prioritize downloading one resource, like an image. Preload an image only if it is absolutely necessary. Despite the fact that the word load appears in the name, the script is not loaded or executed. Rather, it is just scheduled to be downloaded and cached with a higher priority.

Priority Hints – fetchpriority (experimental technology)

The fetchPriority property is a hint given to the browser on how it should prioritize the fetch of the image relative to other images. The fetchpriority property is a hint rather than a directive. The browser will make an effort to honor the developer’s choice. It is also possible that the browser will apply its preferences for resource priority as deemed necessary in case of conflicts.

Note that preload image is mandatory for the browser, while fetchpriority is a hint that might be used, but not always.

<link rel="preload" fetchpriority="high" href="example.png" as="image"/>

Use browser cache

You may instruct the browser to keep the image in the browser’s cache for a certain time. So, once it’s downloaded the browser won’t download it again until the specified expiration time passes. The most popular is to set cache expiration to 1 year. An example of Apache configuration is through the .htaccess:

<IfModule mod_expires.c>
  ExpiresActive on

  ExpiresByType image/bmp                             "access plus 1 year"
  ExpiresByType image/gif                             "access plus 1 year"
  ExpiresByType image/jpeg                            "access plus 1 year"
  ExpiresByType image/png                             "access plus 1 year"
  ExpiresByType image/webp                            "access plus 1 year"
  ExpiresByType image/svg+xml                         "access plus 1 year"
  ExpiresByType image/webp                            "access plus 1 year"
<IfModule mod_headers.c>
    # 1 Year
    <FilesMatch "\.(ico|pdf|flv|jpe?g|png|webp|gif|swf|svg)$">
        Header set Cache-Control "max-age=29030400, public"
        Header unset ETag
        FileETag None

Use image-set() for the background images

For high pixel density screens, the image-set() CSS functional notation allows the browser to select the best CSS image from a list of options.

The CSS specification says:

Delivering the most appropriate image resolution for a user’s device can be a difficult task. Ideally, images should be in the same resolution as the device they’re being viewed in, which can vary between users. However, other factors can factor into the decision of which image to send; for example, if the user is on a slow mobile connection, they may prefer to receive lower-res images rather than waiting for a large proper-res image to load. The image-set() function allows an author to ignore most of these issues, simply providing multiple resolutions of an image and letting the UA decide which is most appropriate in a given situation.


.example-background {
    /* Fallback */
    background-image: url("example.png");
    /* Standard; should be transformed to prefixed versions using Sass or Less */
    background-image: image-set("example.png" 1x, "example-2x.png" 2x);

Displays with lower resolutions will experience better performance because their browser will automatically request the lower resolution image, which automatically will improve the speed loading because the image will be smaller.

Use a CDN – content delivery network

By storing the files for your website at numerous data centers across the world you will serve the assets with the closest server to the user. In other words, when someone visits your website, they can then download your files from the nearest global data center.

Extra tip:

Inline svg element replaced with image element

There are cases where we render a lot of <svg>-s (e.g. icons) and at the same time some of them are invisible for the user. This causes not only the loading of too many resources but also impacts the rendering performance.

To fix the issue replace embedded <svg> elements with <img src="example.svg" loading="lazy"/>.

Say we have several icons rendered as embedded inside HTML. So, instead of:

<svg aria-hidden="true" focusable="false" xmlns="http://www.w3.org/2000/svg"><circle cx="100" cy="100" r="90" stroke="black" stroke-width="3" fill="red"/></svg>
<svg aria-hidden="true" focusable="false" xmlns="http://www.w3.org/2000/svg"><circle cx="50" cy="100" r="90" stroke="black" stroke-width="3" fill="green"/></svg>
<svg aria-hidden="true" focusable="false" xmlns="http://www.w3.org/2000/svg"><circle cx="10" cy="10" r="90" stroke="black" stroke-width="3" fill="blue"/></svg>

Do this:

<img src="icon.svg" loading="lazy"/>
<img src="icon_2.svg" loading="lazy"/>
<img src="icon_3.svg" loading="lazy"/>

Note that the above is not applicable when you render <svg> using <use> with the reference to the existing <svg> element on the page.

Related posts

Leave a Reply

SiteLint Audits: Monitoring in real-time Accessibility, Performance, Privacy, Security, SEO, Runtime Errors and Console Logs