Image Optimization
A Practical Guide for Web Developers to Optimize Images
- Chapter 1 - What is image optimization?
- Chapter 2 - Importance of image optimization
- Chapter 3 - Core web vitals
- Chapter 4 - Checklist for your team
- Chapter 5 - Compress images
- Chapter 6 - Optimizing image format
- Chapter 7 - Resizing images to fit the layout
- Chapter 8 - Lazy loading images
- Chapter 9 - Using CDN for fast download
- Chapter 10 - Platform-specific image optimization
- Conclusion - Why use an image CDN?
- FAQs
Last updated - 14 Oct 2024
This guide primarily targets web developers who want to optimize images for media-heavy web and mobile applications. While we will cover some essential theories to solidify your understanding of the core concepts, the main focus of this guide is on practical tips and techniques.
Based on our extensive experience working with thousands of developers, we have compiled a set of opinionated, actionable recommendations and a checklist to enhance your applications' image performance.
Ready to dive in? Let's get started!
Chapter 1 - What is image optimization?
Image optimization is a set of techniques to reduce image file size without compromising "perceived" image quality. The goal is to make images load faster on web and mobile applications. Techniques that are used for image optimization include:
- Image compression - Reducing the file size of an image while maintaining visual quality using lossy compression techniques.
- Image resizing - Changing the dimensions of an image on the server side to fit the application layout on the front end.
- Image format selection - Choosing the right output image format based on the image content and device.
- Lazy loading - Loading images only when the user is about to see them on the screen.
- Content Delivery Network (CDN) - Using a CDN to deliver images faster to users around the world.
We will cover each of these techniques in detail in the following chapters. But first, let's see an example and understand why image optimization is important.
Quick example of image optimization
Let's take this 1.2MB JPEG image as an example and see how we can optimize it using image compression and format selection.
<!-- Using q to control compression on a scale of 1 to 100 -->
<!-- Original image - 1.2MB -->
<img src="https://ik.imagekit.io/ikmedia/example_image.jpg?tr=f-jpg,q-100" />
<!-- Webp with compression - 72 KB -->
<img src="https://ik.imagekit.io/ikmedia/example_image.jpg?tr=f-webp,q-80" />
<!-- AVIF with compression - 43 KB -->
<img src="https://ik.imagekit.io/ikmedia/example_image.jpg?tr=f-avif,q-80" />
We have put a screenshot instead of rendering actual images because your browser might not support AVIF or WebP format.
Chapter 2 - Importance of image optimization
It is a no-brainer that images are the most engaging content on the web after video. They help convey information, create visual interest, and improve user engagement. But what if those images are not loaded quickly enough?
Slow-loading images on a website leads to -
- Poor user experience - Users are less likely to engage with a website that takes too long to load images.
- Higher bounce rates - Users are more likely to leave a website if images take too long to load.
- Lower conversion rates - Slow-loading images will negatively impact conversion rates on e-commerce websites.
But what is quick enough?
The answer to this question has been very subjective until recently. The performance is relative, what is fast for one user might be slow for another. For example:
- What is fast on a high-speed internet connection might be slow on a poor connection.
- What is fast on a high-end desktop might be slow on a low-end mobile device.
- What is fast for a user in the US might be slow for a user in India.
Often, the methods used by engineering teams to measure "speed" are not always accurate. Most of the time, what we measure in a controlled and simulated environment doesn't match the real-world performance.
This led to the creation of standard user-centric performance metrics that website developers can use to answer the questions confidently - "Is my website fast enough?" and "Are my images loading quickly enough?".
This is what core web vitals are all about. They are a set of metrics that Google has introduced to measure the user experience on a website. They are based on real-world data and are designed to help developers understand how fast their website is loading for users.
Chapter 3 - Core web vitals for image performance
Core Web Vitals are the most crucial user-centric performance metrics that site owners should continuously measure and improve. Google has simplified the measurement of these metrics by providing the Google PageSpeed Insights tool.
A typical report of Google PageSpeed Insights looks like this:
Many metrics are part of Core Web Vitals, but image optimization has a direct impact on Largest Contentful Paint (LCP) and First Contentful Paint (FCP).
Largest Contentful Paint (LCP)
It represents how quickly the main content of a web page loads, specifically, the time from when the user initiates loading the page until the largest image or text block is rendered within the viewport. To provide a good user experience, LCP should occur within 2.5 seconds of when the page first starts loading. Fast-loading images will have a direct positive impact on this metric.
First Contentful Paint (FCP)
It marks the time at which the first content is painted. It is the first impression of the website. For this metric, "content" refers to text, images (including background images), elements, or non-white elements. If you have an image like a banner at the top of the page, its loading time will directly impact the FCP. To provide a good user experience, pages should have a FCP of less than 1.8 seconds.
Chapter 4 - Image optimization Checklist
Here is a checklist for your team to ensure that images on your website are optimized for performance. This checklist is based on the best practices and techniques we will cover in the following chapters.
Learn how to deliver an image in the best possible format.
Resizing images on server-side • On the fly resizing
Chapter 5 - Compress images
Image compression is the process of reducing the file size of an image without significantly affecting its visual quality. There are two types of image compression techniques:
Lossy Compression
Lossy compression reduces file sizes by permanently removing certain information and details from image files. While this can affect image quality, the degree of quality loss can be controlled and is often imperceptible, making the trade-off in size reduction very advantageous for web usage.
Predominantly used in web applications, lossy compression is ideal for balancing image quality with load speed, thereby enhancing user experience and reducing data costs. Formats such as JPEG and WebP are commonly used for lossy compression. These are suitable for photographs and detailed images where a slight loss of quality is acceptable in exchange for significantly smaller file sizes.
Why does lossy compression work really well for web use cases?
Let's compress a 1.2MB JPEG image at different compression levels and see the difference:
Quality: 100, File Size: 1.2 MB
Open Image
Quality: 80, File Size: 162KB
Open Image
Quality: 60, File Size: 93KB
Open Image
You won't notice any difference between the original image (leftmost) and the compressed images, although the file sizes vary significantly. This demonstrates the effectiveness of lossy compression for web use, as it reduces file size dramatically without a noticeable change in "perceived" quality to the human eye.
You should avoid extreme image compression, as there is an optimal balance between file size and quality. Excessive compression results in poor visual quality, negatively impacting user experience. An image CDN like ImageKit.io is valuable for its real-time optimization capabilities. It automatically compresses images to the appropriate level, which balances visual quality & size and allows you to control this compression based on your business requirements.
Lossless Compression
Lossless compression reduces file size without any loss of information. It optimizes the image data by repackaging redundant data and removing unnecessary metadata, ensuring that the original data can be perfectly reconstructed from the compressed data. Lossless compression is crucial for archiving images where preserving the original quality is essential. It is also recommended for images that undergo multiple edits, as it prevents the quality degradation that can occur with repeated saving.
PNG and TIFF are typical formats that employ lossless compression. They are preferred for images requiring high precision and clarity, such as digital graphics, logos, and line art.
We don't recommend using lossless compression for web use cases.
How to compress images?
There are many online and offline tools available to compress images. We highly recommend using only the online tools or an Image CDN as they don't require installation.
Depending on the use case, you can choose the right tool for compressing images:
Use-case | Tool |
---|---|
Very few images. One-time optimization is required. | TinyPNG and Squoosh. |
E-commerce website | Depending on the platform, there could be some built-in optimizations. However, platforms like Magento, WordPress, and Shopify often result in poor visual quality of the images. We recommend using an image CDN like ImageKit.io. For more details on how to display high-quality e-commerce product images, checkout this blog.
|
Custom media-heavy web application | Use an image CDN to automate image optimization. This allows your engineering team to focus on building an engaging visual experience without dealing with its technical complexities.
|
User-generated content | To manage user-generated content effectively, you have two options for image compression: compress at the time of upload and store the compressed images, or use on-the-fly compression via an image CDN. For storage, consider using cloud-based object storage like S3 or opt for ImageKit's Media Library. ImageKit's storage API allows you to compress images and apply various transformations during uploading. You can use the generated media file URLs directly in your application. |
You should always store high-quality master images at the largest resolution needed for desktop use, typically around 1920px wide and under 5MB. This approach lets you tweak compression settings later without losing the original image quality. Having an image CDN that can compress images on the fly is recommended, as it gives your engineering team the flexibility to adjust compression settings without altering the original image.
Chapter 6 - Optimizing image format
Optimizing image format means converting the input image to the right output format before delivering it to the user.
What is the right image format?
Well, it depends on a lot of things. You should consider the following factors -
- Browser and device support - Does the browser support modern image formats like WebP and AVIF?
- Transparency - Does the image require transparency? JPEG doesn't support transparency, so possible options are PNG, WebP, and AVIF.
- Animation - Does the image require animation? GIF and WebP support animation.
- Compression/File size - AVIF is the clear winner in terms of compression and file size. WebP is also good. JPEG is the worst relatively.
- Quality - At similar compression levels, which format delivers superior quality? AVIF leads in quality, with WebP also performing well.
So, the definition of the right image format becomes:
The right image format is the one that provides high quality and the smallest file size based on the image content and device support. This means that AVIF may be suitable for some users, and JPEG may be the better choice for others.
It is easy to get overwhelmed by these factors. But don't worry; follow these guidelines, and you will be good:
- Use SVG for icons, simple graphics, and logos. A vector image is resolution-independent, so it can be scaled to any size without losing quality. All modern browsers support it.
- For photographs and images with complex color gradients, i.e., typical real-world images, AVIF should be preferred. Use WebP as a decent fallback because it is now widely supported. Use JPEG as a last resort for very older browsers and devices.
- For images requiring transparency, use AVIF or WebP. PNG should be your last preference.
- Avoid using GIFs altogether. Convert GIF to MP4 video or animated WebP.
- If you use a content delivery network (CDN), which you should be, then correctly configure caching rules so images are not delivered in unsupported image format from polluted CDN cache. We will talk more about this in the coming chapters.
- Above all, make sure your application logic is simple. Handle complexity on the server-side.
If you're setting up an in-house image processing service, consider the high infrastructure costs, especially for computationally intensive tasks like encoding images in AVIF format. An image CDN like ImageKit.io can streamline image processing for you and efficiently handle scaling during traffic spikes.
How to handle browser support and serve image in the best possible format?
We talked about serving different image formats based on the browser support. But how do you do that?
Technically, you can do it in two ways:
- Using HTML
picture
element - Thepicture
element allows you to define multiple sources for an image based on different conditions. You can use it to serve different format images based on browser support.
<picture>
<source srcset="image.avif" type="image/avif">
<source srcset="image.webp" type="image/webp">
<img src="image.jpg" alt="An awesome image">
</picture>
- Using ImageKit.io - ImageKit.io is an image CDN that can automatically convert images to the right format based on the factors we discussed above. You don't have to change the image URL. This is done by changing the format on the fly and correctly setting the
Content-Type
response header based on format support declared by the browser in theAccept
request header.
<img src="https://ik.imagekit.io/ikmedia/example_image.jpg" />
What's wrong with using picture element?
- The problem with using the
picture
element to serve different formats is that it increases the HTML markup. If you are doing server-side rendering, all users will have to download this extra markup when every page loads. - Another problem is generating and storing multiple variants for the same image. What if a new format comes up tomorrow? You will have to update all the images. This needs to be more scalable.
The second approach is using an image CDN. It always delivers an image in the right format, considering all the above factors. You don't have to change the image URL. In addition, you can control the output format via URL parameters.
How to convert GIF to video or animated WebP?
GIF is not an ideal web format due to its large file size and limited color palette, which supports only 256 colors. It also lack modern features like transparency. For better performance and quality, it is recommended that GIFs be converted to video formats or animated WebP.
Let's convert this GIF - https://ik.imagekit.io/demo/gif-test.gif to webm video and animated WebP to compare sizes.
Stark difference in file sizes, right? 2.3MB Gif vs 165KB WebM video vs 1.4MB Animated WebP.
Convert GIF to video using ImageKit
Use ImageKit GIF to video conversion feature to convert GIF to video. You can then use the HTML5 video tag for playback. ImageKit will automatically take care of video codec and serve VP9 or AV1 encoded video if browser supports it.
<video autoplay loop muted playsinline>
<source src="https://ik.imagekit.io/demo/gif-test.gif/ik-gif-video.mp4">
</video>
Convert GIF to animated WebP
When images are delivered using ImageKit, a GIF is automatically converted to animated WebP for supported browsers. You don't have to do anything.
<img src="https://ik.imagekit.io/demo/gif-test.gif">
Chapter 7 - Resizing images to fit the layout
Resizing an image means changing its dimensions on the server-side per layout requirements before delivering it to the user. Many of us have inadvertently uploaded full-size images directly onto web pages. This is an easy mistake to make, especially when fast internet speeds make large images appear to load swiftly and display properly. However, in practical scenarios, this can significantly degrade performance as users are forced to download excessive data, impacting their experience negatively.
Why resize images on server-side?
Simply put, resizing images to fit the layout is important because it reduces the image's resolution, meaning there are fewer pixels to encode, which results in a smaller file size. Serving a 2000x2000 image in a 200x200 container is inefficient, wasting bandwidth and slowing down image loading times for your users.
How to resize images?
No matter how your media workflow looks, there are only two ways to serve correctly resized images: either you generate and store the correct-size image in advance, or you generate it on the fly.
- Pre-emptive resizing: In this approach, you generate and store multiple variants of the image based on the current application layout (and future needs). This is a good approach if you have a static layout that won't change. However, it is not scalable, and you will end up storing multiple copies of the same image.
- On-the-fly resizing - With this approach, you only store the original image and resize it on the fly based on the application layout. This method is highly scalable and recommended for most use cases because it adapts to varying UI changes and device targets without the need to pre-generate and store every possible image variation. This saves on storage and ensures images are optimally sized in real time, catering to the high variability in user devices.
Pre-emptive resizing using ImageMagick
How to resize images on the fly?
On-the-fly resizing is the most scalable approach. You don't have to worry about storing multiple variants of the same image. You can resize images on the fly using an image CDN like ImageKit.io or by implementing an image resizing service yourself.
Basic resizing 200x200 thumbnail
<img src="https://ik.imagekit.io/ikmedia/example_image.jpg?tr=w-200,h-200" />
AI-based smart cropping to generate meaningful thumbnails
<img src="https://ik.imagekit.io/ikmedia/example_image.jpg?tr=w-200,h-200,fo-auto" />
See the different image transformations available in ImageKit.
How to load the correct image in your application?
We've discussed resizing images to make them suitable for your application. But how do you ensure the correct image loads on each device?
- If your application's layout is simple and consistent across different screen sizes, you can load the image using the
src
attribute. This technique also works on single-page applications (SPAs) where JavaScript generates the layout. - If the layout is complex and adjusts based on screen size and display density, you should use the
srcset
attribute. This lets you specify multiple image options, ensuring the most suitable one is loaded based on the device's screen size. This technique is part of implementing responsive images.
Implementing responsive images
Responsive images are the set of techniques used to load the right image based on device resolution, orientation, screen size, network connection, and page layout. The browser should load an image that fits the layout, and loading it shouldn't result in time & bandwidth wastage. It improves user experience as images load fast and looks crisp to the human eye.
We have written an end-to-end guide on responsive images, but here is what you need to know -
- Use
srcset
withsizes
to let the browser load the right image based on the device's screen size and application layout. This forces you to consider layout and image dimensions. - Avoid using the
picture
element and Client Hints to automate responsive image implementation. This method looks promising on the surface, but it will end up creating too many close variants of the same image. - In most cases, the human eye cannot discern the benefits of a Device Pixel Ratio (DPR) of 3, allowing for the use of smaller images without noticeably reducing quality for the majority of users. Limit serving only 2x images for high-density screens like Retina displays.
- Regardless of the chosen method, select breakpoints thoughtfully and maintain straightforward logic. Focus on your users' most common screen sizes and tailor your images to those dimensions. Creating too many variants of the same image can hinder CDN caching and unnecessarily burden the server.
What is wrong with resizing in HTML using width and height attribute?
Resizing images in HTML using the width
and height
attributes is not recommended. It is a bad practice because the browser downloads the full-size image and then resizes it to fit the layout. This wastes bandwidth and slows down page load times. Always resize images on the server-side before delivering them to the user. Furthermore, a browser-resized image might not look as good and sharp as a server-resized image.
Chapter 8 - Lazy loading images
Lazy Loading Images is a set of techniques in web and application development that defer the loading of images on a page to a later point in time - when those images are actually needed, instead of loading them upfront. These techniques help improve performance, better utilize the device's resources, and reduce associated delivery costs.
We have written a detailed guide on lazy loading images, but here is the gist in the context of image performance.
Primarily, there are two advantages of lazy loading images:
- Performance improvement - This one is obvious. If a page loads fewer resources, then the important resources like CSS, JS, and images on the top will load faster, improving the overall user experience.
- Cost reduction - Serving images from a CDN, S3, web-server or any other provider costs money. If the user never scrolls to the bottom of the page, then why load those images? Lazy-loading images will save you money.
How to lazy load images?
There are multiple ways to lazy load images, but we will suggest you go with the following two:
Native Lazy Loading
The loading
attribute on the img
tag is a native browser feature that allows you to lazy load images without any JavaScript. It is supported in Chrome, Edge, and Firefox.
Here is how you can use it:
<img src="example.jpg" loading="lazy" alt="..." />
- lazy - Deferring the loading of assets till it reaches a certain distance from the viewport.
- eager - loading the assets as soon as the page loads, irrespective of where they are placed on the page, whether above or below the page fold.
- auto - This value triggers default lazy loading. Basically, it's the same as not including the loading attribute.
Intersection Observer API
Intersection Observer API is a JavaScript API that allows you to observe changes in the intersection of a target element with an ancestor element or with a top-level document's viewport. It is supported in all modern browsers.
Here is a working CodePen example taken from our blog post:
We recommend using the native lazy loading attribute as it is supported in most modern browsers. If you need more control, then use the Intersection Observer API. Loading extra JavaScript for lazy loading images is no longer recommended.
If you are using ImageKit front-end SDKs (React, Angular, Vue.js), check the following getting-started guides:
Chapter 9 - Using CDN for fast download
A Content Delivery Network (CDN) is a network of servers distributed across the globe that cache and deliver content to users based on their geographic location. CDNs are used to deliver content, including images, videos, and other static assets, faster to users around the world.
Why use a CDN for images?
- Faster delivery - CDNs cache images on servers closer to the user, reducing latency and improving load times.
- Scalability - CDNs can handle large volumes of traffic and scale automatically to meet demand.
- Reliability - CDNs provide redundancy and failover protection, ensuring that images are always available.
- Security - CDNs offer security features like DDoS protection and SSL encryption to protect your web server from common attacks.
How to configure CDN for images?
Configuring a CDN for images depends on the CDN provider and your image server configuration. In general, here are the factors to keep in mind:
- If your server changes format on the same URL based on the request
Accept
header, then send theVary: Accept
response header to cache a different image copy on the CDN. This is important if you serve WebP, AVIF, and JPEG images on the same resource URL. Most CDN providers support this standard except Akamai and Azure CDN from Microsoft. - Use the
Cache-Control
header to set the cache duration for images. You can set it to a year for images that don't change frequently. - Correctly set the
Content-Type
header based on the image format. - Avoid modifying content based on the
User-Agent
request header. First, it is not 100% reliable, and second, it will hit the cache-hit ratio adversely. - If possible, use CloudFront functions or something similar to normalize the image URL and cache key before caching. This will help in the cache-hit ratio.
The exact steps to configure a CDN for images could vary from provider to provider, and it can be tricky to get it right. We recommend using an image CDN like ImageKit.io, which automatically takes care of these things for you. It comes with CloudFront CDN.
Chapter 10 - Platform-specific image optimization
Most site generators and e-commerce platforms have built-in image optimization features. However, they all lack the control and flexibility you need as a web developer to ensure the best image performance. Let's compare some popular platforms and the ideal way to automate image encoding and optimization.
Image optimization in Next.js
Next.js is a popular React framework that provides server-side rendering and static site generation. The Next.js Image
component extends the HTML <img>
element with features for automatic image optimization:
- Format Optimization: Automatically deliver images in the optimal format for each device, utilizing modern formats such as WebP and AVIF.
- Visual Stability: Automatically prevent layout shifts during image loading.
- Lazy Loading: Images load only when they become visible in the viewport, utilizing native browser lazy loading techniques, complemented by optional blur-up placeholders.
- Server-Side Resizing: Perform on-demand resizing of images using the
width
andheight
attributes.
You can use Next.js built-in optimizations for a small site. For a media-heavy site, you should use an image CDN like ImageKit.io to automate image optimization. Next.js provides custom loader support, so you can use ImageKit.io as a custom loader to serve optimized images.
Here is an example of using ImageKit as a custom loader in Next.js:
import Image from "next/image";
const imageKitLoader = ({ src, width, quality }) => {
if(src[0] === "/") src = src.slice(1);
const params = [`w-${width}`];
if (quality) {
params.push(`q-${quality}`);
}
const paramsString = params.join(",");
var urlEndpoint = "https://ik.imagekit.io/your_imagekit_id";
if(urlEndpoint[urlEndpoint.length-1] === "/") urlEndpoint = urlEndpoint.substring(0, urlEndpoint.length - 1);
return `${urlEndpoint}/${src}?tr=${paramsString}`
}
const MyImage = (props) => {
return (
<Image
loader={imageKitLoader}
src="default-image.jpg"
alt="Sample image"
width={400}
height={400}
/>
);
};
Other useful resources:
- Next.js image optimization blog post and getting started guide.
- Automate image optimization in WordPress using ImageKit plugin.
- Load high-quality compressed product images on Shopify and Magento using ImageKit.
Conclusion - Why use an image CDN like ImageKit?
To complete image optimization checklist, your engineering team needs a powerful media API to automate most image optimization and transformation tasks. This is where an image CDN comes into play.
Automate image format selection and compression
ImageKit's automatic format conversion and optimal compression reduce significant complexity for your web developers. Based on multiple factors, including browser support, ImageKit can deliver WebP, AVIF, and JPEG images on the same image URL.
This means you don't have to worry about how to modify HTML to request the correct image or how to store multiple variants of the same image. ImageKit takes care of it for you.
On-the-fly resizing for responsive images
Implementing responsive images using srcset
and sizes
is a relatively complex task. Your team also has to worry about the generation and storage of all the variants. ImageKit can resize images on the fly based on URL parameters, making it easy to serve correctly sized images.
For example, to resize an image to 200x200 pixels, you can use the following URL:
<img src="https://ik.imagekit.io/ikmedia/example_image.jpg?tr=w-200,h-200" />
To resize an image to 200x200 pixels and apply smart cropping, you can use the following URL:
<img src="https://ik.imagekit.io/ikmedia/example_image.jpg?tr=w-200,h-200,fo-auto" />
To add a text overlay on the image, you can use the following URL:
<img src="https://ik.imagekit.io/ikmedia/example_image.jpg?tr=w-200,h-200,l-text,i-hello,l-end" />
An example picked from our text overlay blog.
This is just the tip of the iceberg. ImageKit provides a wide range of image transformations that can be applied on the fly. Bonus: The same API works on videos, making it a one-stop solution for all your media needs.
FAQs
How to monitor image performance?
We recommend using Google PageSpeed Insights to monitor image performance. It provides a detailed report on how images are affecting your website's performance. You can also use Lighthouse for a more in-depth analysis. Optimize large contentful paint (LCP) and first contentful paint (FCP) to improve image performance.
How to optimize images for SEO?
Use sensible file names and alt text for images. Use descriptive file names that include relevant keywords. Add alt text to images to describe the content of the image. This helps search engines understand the context of the image and improves SEO.
What is Data-Saver mode in Chrome?
Mobile browsers like Chrome Mobile and Opera Mobile allow users to activate a Data Saver mode. With this mode enabled, the browser sends a Save-data
header within the request. By identifying this header, a web page can customize and deliver an optimized user experience to cost—and performance-constrained users.
ImageKit supports Data Saver mode to further optimize images for users on slow connections.