On this page
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.

How do you fix slow loading images on your website? What’s causing them? There are ways to optimize it, and let’s dive into it deeper.

Why optimize images?

Optimizing images is crucial for several reasons related to website performance and search engine visibility:

  • Improved user experience: when images load quickly, users can access the content they want without delays. This enhances the overall browsing experience and reduces frustration.
  • Faster page load times: images are often a significant factor in page load times. By optimizing and compressing images, websites can reduce the file size and load them more quickly. This results in faster overall page load times, allowing users to access the content faster.
  • Reduced data usage: faster loading images consumes less data, which is especially beneficial for users with limited data plans or slower internet connections. Optimized images help reduce the amount of data that needs to be transferred, resulting in a more efficient browsing experience.
  • Better SEO performance: improving SEO and rankings on search engines since site speed is a ranking factor, and faster loading images contribute to improved website performance.
  • Improved accessibility: faster loading images can benefit users with disabilities who rely on assistive technologies. When images load quickly, screen readers and other assistive devices can process and present the content more efficiently, ensuring a smoother browsing experience for all users.
  • Hosting cost reduction: potentially reducing the hosting cost if you pay-as-you-go for the transfer data.

Strategies for making images load faster on websites

Optimizing images file size

Optimizing images refers to the process of reducing the file size of images through selecting the most efficient image format, dimensions, and resolution without compromising their quality.

This step should be fairly easy. Use the tool to optimize your images to reduce their size while maintaining or improving their visual quality. One of the tools could be ImageOptim (Mac only) or pngquant or Squoosh. These tools will help you to optimize your images.

While this type of optimization is usually safe, it is important to note that sometimes some image meta data may be removed during optimization. For example, image date creation. Some tools are capable of preserving such metadata.

Moreover, you need to be careful when overwriting previous images with the same, but optimized ones. While the image itself does not change, its size often changes. If you have any functionalities that depend on the size of the image file, you must remember to update them.

Client-side image optimization techniques before uploading

Client-side image optimization techniques before uploading involve compressing images in the browser before sending them to the server. This approach can significantly reduce the file size of images, leading to faster upload and download times, reduced memory consumption, and saved server space.

Accessing the image for upload for processing through client-side JavaScript (JS) before upload is possible through the canvas. Read more about it in article called How to compress the image on the client side before uploading.

Implementing responsive images with srcset and sizes

Responsive images refer to images on a website that are designed to adapt and display optimally on various screen sizes, resolutions, and orientations of devices. This adaptation is crucial for providing an optimal user experience across different devices and screen resolutions.

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.

Deferring offscreen image loading with lazy loading technique

Lazy loading images refers to a web design technique where images are not immediately displayed on a webpage but instead loaded progressively as the user interacts with the page, such as scrolling or clicking. This approach contrasts with traditional image loading methods, where all images are loaded at once, regardless of their visibility in the viewport.

To implement lazy loading of images in the browser, you can utilize 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 image with loading=”lazy” attribute
<img src="example.png" alt="A description of the image." width="500" height="250" loading="lazy">

Preloading images for faster loading times

You can instruct the browser to preload crucial images in the document’s <head> using link rel="preload" feature.

The link rel="preload" feature allows you to specify resources that your webpage will need shortly, instructing the browser to start loading these resources early in the page lifecycle, before the main rendering process begins. This proactive loading strategy aims to ensure that these resources are available sooner, reducing the likelihood of blocking the page’s render and thereby enhancing performance.

Despite the term load in its name, link rel="preload" does not immediately execute scripts but merely schedules them for download and caching with higher priority.

Example link rel="preload" for the image
<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.

Boosting performance with priority hints and fetchpriority

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 the preload image is mandatory for the browser, while fetchpriority is a hint that might be used, but not always.

Example link rel="preload" with fetchpriority attribute for the image
<link rel="preload" fetchpriority="high" href="example.png" as="image">

Leveraging browser caching

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:

Apache htaccess configuration for caching images
<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

Utilizing content delivery networks (CDNs)

Utilizing Content Delivery Networks (CDNs) for images involves leveraging a network of distributed servers to efficiently deliver images to users worldwide.

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

This approach significantly reduces latency, improves loading times, and enhances overall user experience.

Additional hints for consideration

Lazy loading with delay technique

Lazy loading is a technique in web and application development that delays the loading of certain resources, such as images, until they are needed by the user. This means that images are loaded only when they enter the user’s viewport or come into the visible area of the web page, rather than loading all images as soon as the page loads.

The weakness of this technique is that it loads the image when it appears in the viewport, and this is not always desirable. Ideally, it would be possible to load an image not only when it appears in the viewport but also with an additional delay. This solution would allow us to avoid loading images when the user is scrolling through the content. It is very useful when the user simply scrolls through the content quickly and is not necessarily interested in loading all the images that appear in the viewport.

Read more about lazy loading and delay rendering technique in the article Improved lazy loading for images, video, and audio.

Use at least protocol HTTP/2

The Hypertext Transfer Protocol (HTTP) is a foundational protocol for the World Wide Web that enables communication between clients and servers. There are currently three protocols: HTTP/1.1, HTTP/2, and HTTP/3.

We will focus here on HTTP/2 and the difference between it and HTTP/1.1. HTTP/3 is the best option, but it is not yet as available as HTTP/2.

The HTTP/2 protocol is designed to improve web performance, reduce latency, and enhance security by introducing multiplexing, server push, binary format, and other performance optimizations.

One of the major differences between HTTP/1.1 and HTTP/2 is in the way resources are loaded. This is called multiplexing. In HTTP/1.1, resources are loaded one after the other, which means that if one resource cannot be loaded, it blocks all the other resources behind it. On the other hand, HTTP/2 is able to use a single TCP connection to send multiple streams of data at once, ensuring that no one resource blocks any other resource.

The easiest way to determine what HTTP protocol is used for serving the content is to use browser developer tools.

To view the network protocol used in Chromium-based browsers Developer Tools, you can follow these steps:

  • Open developer tools.
  • Open the website for which you want to check the protocol version.
  • Go to the network tab.
  • Right-click on the Name/Status menu bar in the Network tab.
  • From the dropdown menu, select the Protocol option.
  • Reload the URL inside the web browser, and you will notice the protocol version being displayed alongside the network requests.
Chromium-based browsers developer tools and network tab that demonstrates how to show the protocol column

Faster loading background images with image-set()

The image-set() CSS function is designed to allow the browser to select the most suitable image from a given set based on the device’s capabilities, such as its pixel density. This feature is particularly useful for optimizing image loading times and resource usage on various devices and networks.

By specifying a set of images along with their associated resolutions, the browser can choose the most appropriate image to display, considering factors like screen resolution and bandwidth availability. This approach helps in delivering optimized content to users, enhancing the performance and responsiveness of web applications.

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 by simply providing multiple resolutions of an image and letting the UA decide which is most appropriate in a given situation.
Example CSS code that uses image-set() function
.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 will automatically improve the speed of loading because the image will be smaller.

Replacing inline SVG elements with image elements

There are cases where we render a lot of <svg>-s (e.g., icons), and at the same time, some of them are invisible to 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" alt="">
<img src="icon_2.svg" loading="lazy" alt="">
<img src="icon_3.svg" loading="lazy" alt="">

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

Speed up loading small images

Speeding up the loading of small images may depend on the case. Sometimes it will be more beneficial to use sprites, e.g., for emoticons, and sometimes a CDN will be a better solution, e.g., for thumbnails.

There are cases that image could be part of the HTML using the data: URL scheme in base64 format. Embedding an image directly into an HTML document using the data: URL scheme allows you to include images without needing to make separate HTTP requests or store them on a server. This can be particularly useful for small images that are part of the page content, reducing the number of HTTP requests and potentially improving load times.

Example HTML with embedded image using base64
<img alt="Default avatar" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAARgAAAEYCAMAAACwUBm+AAAAM1BMVEWy5vq36Pq86fvA6/vF7PvK7vzP7/zU8fzZ8/3d9P3i9v3n9/3s+f7x+v72/P76/v////+etrTMAAAC5klEQVR4Xu3cDY7cIAyGYUNIAuHP9z9tq1G1kdqgHaJtpIH3OcKnDGODQYYGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFjcyyJfYNaQ9UsOqxGIuKPqX+rhiCXppTR3NDZpU7Iyra1qm9ZNJnXoNw6Zkcn6rWzIpZkMubSTYX1hndn1bbtMxFZ9W7Uyj6QdkkzDaRfHB3MtTf7B8MlE7RRlCla7WZmB125eZlC0W5EJLHrDwi/pmp+3iKGU0Vuo7hrcrBsObD4EvSWw9l5Ls5Z3lHh6k4yLYAiGYAiGYAiGYAiGloCzk1OcdWeTvc1Vb1k5brtmOVa6VOYdMmPgbGWJaajarc48sMnopuNUqaHwn3Rt006bzMFU7VKNTMLTJzUUVphrK8VdQ2KL6pqt3LG4tjMY0xDZ0uROZJ+l3l1gSKYuMiVX+3PhmzlzIRlyOS1ZG/Iic/Otjnp69tB/HFYgYkPRk5bwFQuWPaSXsD+wtgAAYNzmX3ZnpYN1u3/ZnJHR2C0WPakmv8gbFp/0pFriZmUYds96oYZvsllC1Qt5t6OUtU3JdbzCOVJxbM5vpSeaM5a2vBv5VC7qGw5zEeihb4huhJdX24qTv7ii70l2xK3u0377znpdxp6BOW7P6FUz9gRiNF+JxqHnFq12ylZebB57mH7XbsEZ48Loz2FEfUwce/r7vjrB6znjv7nj9UF+/Buhw98jNfooM960atuY865BHxXkU2R9VB6sH2gbtSvY9GHbaJ1125gddtGHFZaYBkuj9OPtEsEQDJ3SyXx04Uvpu+vD9uHOlNpGPFti26HtoCFoCOzGNLiijyhOPs16/PdsyrHKR7JbyPqf5PDhY4rG+Vj1R9XonZEh2NXHoj+gRL9aGY3bfEx6U4p+c8MPiIf0dkAphXMkfA7GOed/i+mPnNMf0f/m3IN5AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4BcZ5MIUy1/oSgAAAABJRU5ErkJggg==">

Limitations and pitfalls for base64 encoded images

  • Increasing HTML size: including large numbers of images directly in HTML increases the size of the HTML itself.
  • Increasing the image size: base64 encoding uses a set of 64 characters (hence the name) to represent binary data. This means that each character in the encoded string represents exactly 6 bits of the original data. Since 8 bits make up a single byte, base64 encoding increases the size of the data by approximately 33%.
  • Maximum image size in the data: URL: browsers typically limit the maximum size of a data: URL to around 32KB to 64KB.
  • Security: be cautious when handling user-uploaded images. Ensure that any base64 encoded images are properly sanitized to prevent security vulnerabilities like XSS attacks.


In summary, optimizing images is a multifaceted approach that improves website performance, enhances user experience, boosts SEO, saves costs, increases conversion rates, and ensures better responsiveness on mobile devices.

Related posts


Leave a Reply

Real-user monitoring for Accessibility, Performance, Security, SEO & Errors (SiteLint)