Image Optimization for Web
Important Links
➜ Read Adobe article on Lossy vs Lossless Compression
Introduction
We’ve all visited a website that took forever to load, right? Chances are, it was due to unoptimized images!
So, in this artcile, let’s learn the key factors to consider when optimizing images for the web—covering formats, compression, lazy loading, and even automation with code examples.
Image Formats and When to Use Them
Choosing the right image format can make a huge difference in file size and quality. Let’s quickly go over the most common formats and when to use them.
- JPEG – Best for photos with lots of colors.
- PNG – Best for transparent backgrounds.
- WebP – Great modern format, better compression.
- AVIF – Newer than WebP, even better but less supported.
- SVG – Best for vector graphics.
- GIF – Use WebP instead for animations!
Image Compression Techniques
What is Image Compression?
Image compression reduces the file size of an image, making it load faster on the web. There are two main types:
Lossy Compression – Reduces file size by permanently removing some image data. Lossless Compression – Reduces file size without losing any image data.
What is Lossy Compression?
Lossy compression removes some image details permanently to make the file smaller. This results in lower quality but significantly reduced file size.
Common Lossy Formats:
- JPEG – Best for photos & web graphics.
- WebP (Lossy mode) – Smaller than JPEG, better quality.
- AVIF (Lossy mode) – Even better than WebP, but not fully supported.
Pros & Cons of Lossy Compression
Pros:
- Smaller file sizes (great for faster loading websites).
- Good enough quality for most cases.
Cons:
- Quality loss (irreversible once compressed).
- Artifacts appear at high compression levels.
What is Lossless Compression?
Lossless compression reduces file size without losing any image quality. The image looks the same but is optimized for storage.
Common Lossless Formats
- PNG – Best for transparent images, icons, and logos.
- WebP (Lossless mode) – Better compression than PNG.
- AVIF (Lossless mode) – Newer format, better than PNG & WebP.
- GIF – Used for animations, but outdated.
Works best for logos, icons, and sharp graphics.
Pros & Cons of Lossless Compression
Pros:
- No quality loss (perfect for detailed images).
- Great for transparency (PNG).
Cons:
- Larger file sizes compared to lossy formats.
- Not ideal for large photos (PNG can be too big).
When to Use Lossy vs. Lossless?
Use Lossy Compression When:
- You need small file sizes for faster loading websites.
- The image is a photo or complex graphic (JPEG/WebP).
- A little quality loss is acceptable.
Use Lossless Compression When:
- You need perfect image quality (logos, icons, UI elements).
- The image has text or sharp edges (PNG/WebP lossless).
- You need transparency (PNG).
How to Compress Images?
Online Tools for Compression
- TinyPNG – Compresses PNG & JPEG automatically.
- Squoosh.app – Lets you control compression levels (by Google).
- ImageOptim – Great for Mac users.
And if you have a lot of images and are running short on time, I’ve got you covered. Open VS Code, create a Node.js app, and then create a file named compression.js. Install the necessary dependencies, store all the images in the images folder, and then run the command:
mkdir image-optimization
cd image-optimization
npm init -y
npm install imagemin imagemin-mozjpeg imagemin-pngquant imagemin-webp
node compression.js
In package.json:
"type": "module",
Write the code in compression.js
file
import imagemin from 'imagemin';
import imageminMozjpeg from 'imagemin-mozjpeg';
import imageminPngquant from 'imagemin-pngquant';
import imageminWebp from 'imagemin-webp';
async function optimizeImages() {
await imagemin(['images/*.{jpg,png}'], {
destination: 'compressed-images',
plugins: [
imageminMozjpeg({ quality: 75 }),
imageminPngquant({ quality: [0.6, 0.8] })
]
});
console.log('Images optimized!');
}
async function convertToWebP() {
await imagemin(['images/*.{jpg,png}'], {
destination: 'webp-images',
plugins: [
imageminWebp({ quality: 75 })
]
});
console.log('Images converted to WebP format!');
}
(async () => {
await optimizeImages();
await convertToWebP();
})();
This command will compress images in bulk, store them in the compressed-images folder, and convert JPG and PNG images to WebP format and store them in webp-images folder. You can also check the sizes of the compressed and converted images using the command:
ls -lh compressed-images
ls -lh webp-images
Responsive Images
Responsive Images (Serving Different Sizes)
Instead of serving large images to all devices, let’s use srcset
attribute to provide different image sizes.
<img src="image-800.jpg" srcset="image-400.jpg 400w, image-800.jpg 800w, image-1200.jpg 1200w" sizes="(max-width: 600px) 400px, (max-width: 1200px) 800px, 1200px" alt="Optimized image">`
Now because of this, browsers will automatically load the best size!
src=“image-800.jpg”: This is the default image source that will be used if the browser does not support srcset.
srcset=“image-400.jpg 400w, image-800.jpg 800w, image-1200.jpg 1200w”: This attribute provides a list of image sources with their corresponding widths. The browser will choose the most appropriate image based on the device’s screen size and resolution.
image-400.jpg 400w: Image with a width of 400 pixels.
image-800.jpg 800w: Image with a width of 800 pixels.
image-1200.jpg 1200w: Image with a width of 1200 pixels.
sizes="(max-width: 600px) 400px, (max-width: 1200px) 800px, 1200px": This attribute defines a set of media conditions (e.g., screen widths) and indicates what image size the browser should use at different viewport widths.
(max-width: 600px) 400px: If the viewport width is 600 pixels or less, use the 400-pixel wide image.
(max-width: 1200px) 800px: If the viewport width is between 601 and 1200 pixels, use the 800-pixel wide image.
1200px: If the viewport width is greater than 1200 pixels, use the 1200-pixel wide image.
alt=“Lesson Image”: This provides alternative text for the image, which is used for accessibility and displayed if the image cannot be loaded.
Lazy Loading
Load Images Only When Needed.
Why Lazy Loading Matters Lazy loading prevents images from loading until they are about to be displayed on the screen. This reduces initial page load time, saves bandwidth, and improves performance, especially for long-scrolling pages.
How Lazy Loading Works When an image is below the fold (not visible when the page loads), the browser skips downloading it until the user scrolls down to it.
Since HTML5, we can enable lazy loading by simply adding the loading=“lazy” attribute to an <img>
tag.
<img src="dog-barking.jpg" loading="lazy" alt="Dog Barking">
Image Naming & Alt Attributes
Why Image Naming Matters
- SEO Benefits: Search engines use file names to understand images.
- Accessibility: Helps screen readers describe images to visually impaired users.
- Better Organization: Descriptive names make it easier to manage images.
Best Practices for Naming Images
- Use Descriptive, Keyword-Rich Names
<div>
<!-- Descriptive filenames -->
<img src="sunset-beach-california.jpg" alt="Sunset Beach California" />
<!-- Don't -->
<img src="IMAGE123.jpg" alt="" />
</div>
- Use Hyphens Instead of Underscores
Search engines treat hyphens as word separators, but underscores are ignored.
<div>
<!-- Using Hyphens -->
<img src="sunset-beach-california.jpg" alt="Sunset Beach California" />
<!-- Don't -->
<img src="sunset_beach_california.jpg" alt="Sunset Beach California" />
</div>
- Keep It Short and Relevant - Don’t add unnecessary details.
<div>
<!-- Keep It Short and Relevant -->
<img src="dog-on-beach.jpg" alt="Dog On Beach" />
<!-- Don't -->
<img
src="screenshot-2025-02-10_17-24-35.jpg"
alt=""
/>
</div>
- The Importance of
alt
Attributes
The alt
attribute provides alternative text for images. It improves SEO, accessibility, and user experience when images fail to load.
Example of a Good alt
Text:
<img src="dog-playing-fetch.jpg" alt="Golden Retriever playing fetch in a park">
Bad Examples:
Empty alt
Text (Only okay for decorative images)
<img src="banner.jpg" alt="">
Picture Element
The picture Element: Serve Different Image Formats & Sizes
Why Use picture? The picture element allows us to serve different images based on:
- Screen size (Mobile vs. Desktop)
- Browser support (Use WebP if supported, fallback to JPEG)
<picture>
<source srcset="image.avif" type="image/avif">
<source srcset="image.webp" type="image/webp">
<img src="image.jpg" alt="Beautiful mountain landscape">
</picture>
How It Works
- Browsers that support AVIF → Load image.avif.
- Browsers that support WebP → Load image.webp.
- Fallback to JPEG → Loads image.jpg if AVIF & WebP aren’t supported.
<picture>
<source media="(max-width: 600px)" srcset="small-image.jpg">
<source media="(max-width: 1200px)" srcset="medium-image.jpg">
<img src="large-image.jpg" alt="City skyline at sunset">
</picture>
How It Works
- Small screens (<600px width) → Loads small-image.jpg
- Medium screens (<1200px width) → Loads medium-image.jpg
- Large screens → Loads large-image.jpg
So that’s pretty much all for this article. I hope it helped you. And with this I’ll see you in the next one. Till then bye bye.