Image
Images are an integral part of the web. They are used to convey information, enhance the visual appeal of a website, and improve user engagement. However, images can also be a significant source of performance bottlenecks if not optimized properly
- When a picture has an area that is filled with exactly the same colour, it is known as flat colour
Image Formats
Some of the most commonly used image formats on web are:
Comparison of Popular Image Formats
Format | File Extension | Lossy/Lossless | Typical Uses | Advantages | Disadvantages |
---|---|---|---|---|---|
JPEG | .jpg , .jpeg | Lossy | Photographs, images with continuous tones | High compression ratio, widely supported | Can degrade image quality with repeated editing |
PNG | .png | Lossless | Graphics with transparency, logos, icons | Supports transparency, lossless compression, good color accuracy | Larger file sizes than JPEG |
WebP | .webp | Lossy or lossless | Web images, photographs | Smaller file sizes than JPEG and PNG, supports transparency and animation | Less widely supported than JPEG or PNG |
AVIF | .avif | Lossy or lossless | Web images, photographs | Smaller file sizes than JPEG and PNG, supports HDR, wider color gamut | Less widely supported than JPEG or PNG |
GIF | .gif | Lossless | Animated images, simple graphics | Supports animation, lossless compression, widely supported | Limited color palette (256 colors), larger file sizes than PNG |
SVG | .svg | Lossless | Vector graphics, logos, icons | Scalable, high-quality graphics, small file sizes | Can be complex to edit, might not render consistently across different browsers |
NOTE
Lossy formats compress images by discarding some data, resulting in smaller file sizes but potential image quality degradation. Lossless formats compress images without losing any data, preserving the original image quality
JPEG
Joint Photographic Experts Group (JPEG) is a lossy image format that is widely used for photographs and images with continuous tones
- Most widely used
- Good for photographs and images with continuous tones
- Images with many different colours
- Lossy compression
- High compression ratio
- Can be compressed to a smaller file size
- Supports 24-bit colour
PNG
Portable Network Graphics (PNG) is a lossless image format that is commonly used for graphics with transparency, logos, and icons
- Supports transparency (old browsers such as IE6 doesn't support)
- Lossless compression
- Good colour accuracy
- Larger file sizes than JPEG
- Supports 24-bit colour
- Images with fewer colours or large areas of same colour
- Used mainly for logos and place where image background transparency is needed
- Convert PNG to JPEG if no special requirement is there
- Use WebP image format if transparency is required, Use a backup PNG
src
as WebP is not yet widely supported as of now
WebP
Alternative to JPEG/PNG
Smaller file sizes compared to JPEG and PNG
It can be used for both lossy (JPEG) and losses (PNG) image compression
It also supports transparency like PNG
Less support as of now, we can use JPEG/PNG as a fall back image:
html<picture> <source width="100%" type="image/webp" srcset="riga.webp" /> <img width="100%" src="riga_cjpeg_dssim.jpg" alt="Riga, Lativa" /> </picture>
AVIF
AVIF is a newer format that offers superior compression compared to JPEG and PNG, especially for images with complex details or high dynamic range (HDR) content
<picture>
<source type="image/avif" srcset="snow.avif" />
<img alt="Hut in the snow" src="snow.jpg" />
</picture>
GIF
- Short animations
According the GIF89a Specification the GIF is not intended for animations
As a result when a video is converted to GIF the file size increase
So most of the websites like twitter, Facebook etc,. Use video files for animations as they are much smaller than GIF's. These video files can be of MP4 or WebM format
Some tips to convert GIF to videos:
Reduce the video colours to 256 colours (GIF supports only 256 colours)
Remove audio
Using FFmpeg tool to convert GIF to an MP4 or a WebM video, like:
bashffmpeg -i my-animation.gif -b:v 0 -crf 25 -f mp4 -vcodec libx264 -pix_fmt yuv420p my-animation.mp4
bashffmpeg -i my-animation.gif -c:v libvpx-vp9 -b:v 0 -crf 41 my-animation.webm
WebM is a relatively new file format and WebM videos are much smaller than MP4 videos
WARNING
Not all browsers support WebM so it makes sense to generate both
Usage:
html<video loop autoplay muted playsinline controls="false" src="goats.mp4" />
OR
html<picture> <source type="video/mp4" srcset="goats.mp4" /> <source type="image/webp" srcset="goats.webp" /> <img src="goats.gif" alt="Goat" /> </picture>
OR
html<video autoplay loop muted playsinline> <source src="my-animation.webm" type="video/webm" /> <source src="my-animation.mp4" type="video/mp4" /> </video>
Mobile browsers won't auto play videos unless they are muted
SVG
Scalable Vector Graphics (SVG) is an XML-based vector image format for defining two-dimensional graphics, having support for interactivity and animation
- The SVG specification is an open standard developed by the World Wide Web Consortium since 1999
<svg role="img" aria-labelledby="icon-title icon-desc">
<title id="icon-title">Pickling Solution</title>
<desc id="icon-desc">
The secret to good pickled cheese is good pickling.
</desc>
<!-- svg content -->
</svg>
Benefits of <svg>
:
- Can be displayed as regular
<img>
- Can be incorporated in HTML document
- Can be defined once and used many times
- Can be styled using CSS
- Can be made accessible
- As it made up of text, it can be compressed using
GZip
orBrotli
For basic, uncomplicated, or decorative images, use the <img>
tag and reference the SVG as a file
- Renders lighter and faster pages overall (versus inline SVGs) and allow for easier maintenance on SVGs that you use in multiple places
<img
role="img"
class="lightbulb"
alt="Lightbulb moment!"
src="https://upload.wikimedia.org/wikipedia/commons/2/2b/BulbIcon.svg"
/>
<!--or-->
<img
role="img"
class="lightbulb"
aria-label="Lightbulb moment!"
src="https://upload.wikimedia.org/wikipedia/commons/2/2b/BulbIcon.svg"
/>
For more complex or essential SVGs, you should consider adding the SVG as markup into the HTML
- The page is now potentially heavier and slower
- But you have more options with JavaScript and CSS to manipulate the styles and animations of the images
<svg
role="img"
aria-labelledby="lightbulb11 description11"
version="1.1"
class="hotpink"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
x="0px"
y="0px"
viewBox="0 0 32 32"
style="enable-background:new 0 0 32 32;"
xml:space="preserve"
fill="currentColor"
width="1em"
height="1em"
>
<title id="lightbulb11">Lightbulb moment!</title>
<desc id="description11">I have a great idea.</desc>
<path
d="M11 24h10v2H11zm2 4h6v2h-6zm3-26A10 10 0 0 0 6 12a9.19 9.19 0 0 0 3.46 7.62c1 .93 1.54 1.46 1.54 2.38h2c0-1.84-1.11-2.87-2.19-3.86A7.2 7.2 0 0 1 8 12a8 8 0 0 1 16 0a7.2 7.2 0 0 1-2.82 6.14c-1.07 1-2.18 2-2.18 3.86h2c0-.92.53-1.45 1.54-2.39A9.18 9.18 0 0 0 26 12A10 10 0 0 0 16 2"
/>
</svg>
Modern Image Delivery Techniques
You want your website to be blazing fast, so you have minified and compressed all the files delivered to the user. But still there is a significant delay in page loading time. This is because of the images being used on the web page
According to some analysis of website loading time, it was concluded that nearly 50% of the network traffic was being consumed by the images. Which requires is a lot of network bandwidth. So, to improve the page load time we need to optimize the images and the way they are being delivered
As per google lighthouse, here are 4 Simple ways of Image Optimizations
Network Info can help in image optimization, like check if the user's network is slow, then we can send smaller images or less images
navigator.connection.type;
- Network type that browser usesnavigator.connection.downlink
- Effective bandwidth estimatenavigator.connection.rtt
- Effective round-trip time estimatenavigator.connection.downlinkMax
- Upper bound on the downlink speed of the first network hop
Avoid Base 64 Encoding (Images embedded as Base64 in HTML/CSS/JS) because:
- Images Block the Rendering of the Page
- Images are 20-30% larger
- Caching is limited
- Difficult to reference more than once
- The only advantage of this is Fewer Request
Quality
Quality of the images matter, a blurry or pixelated image depletes the user experience. So, we want to delivery images which have the similar image quality of the original but are much smaller in size
Lighthouse Recommends 85% quality on all images
Example:
bashmagick --quality 85 riga.jpg riga85.jpg
Online tools can also be used like:
Instead of setting the quality to fixed, we can use automated quality finders like:
Butteraugli
SSIM: Structural SIMilarity
- bash
cjpeg-dssim jpegoptim riga.jpg
Pages to refer:
Image Dimensions
Using responsive images decreases the page loading time
If the website is viewed on a desktop we need a large image, but if the same website is being viewed on a mobile phone then we can use the smaller image as the view-port is smaller. This will reduce the size of the image being delivered to the mobile, thus decreasing the page load time. Which will enhance the user experience
We can load different images depending on the screen size using the srcset
attribute of img
tag. We will add all differently sized image sources and let the browser select the image according to the screen size or pixel density of the device
srcset
is a set of one or more strings separated by commas indicating a set of possible image sources for the user agent to useUsage:
html<!-- Change image depending on DPR (Device Pixel Ratio) --> <img src="cat-500px.jpg" srcset="cat-500px.jpg 1x, cat-1000px.jpg 2x, cat-1500px.jpg 3x" atl="cat" /> <!-- Change image depending on screen width and (DPR) --> <img src="cat-500px.jpg" srcset="cat-500px.jpg 500w, cat-1000px.jpg 1000w, cat-1500px.jpg 1500w" atl="cat" />
Also using
sizes
we can optimize even more.sizes
lets us use different images based on media querieshtml<img src="cat-500px.jpg" srcset="cat-500px.jpg 500w, cat-1000px.jpg 1000w, cat-1500px.jpg 1500w" atl="cat" sizes="(min-width: 760px) calc(50vw - 2em), 100vw" />
Use the
w
unit (instead ofpx
) to write width descriptors. For example, a 1024px wide image would be written as1024w
WARNING
srcset
is not widely support as of now, so use a fall-back image sourcesrc
.The resource specified by the
src
attribute should be large enough to work well on all device sizes.
DANGER
25% (percentages cannot be used with the sizes attribute)
Images with higher resolutions are larger in size and take longer to load. To optimize the loading time of images, we can use the srcset
attribute to provide multiple image sources with different resolutions
- Images for web should be not more than 72 ppi (pixels per inch)
Resolution | Image File Size (approx.) | Image Dimensions (approx.) | Description |
---|---|---|---|
72 ppi | 100 KB | 1920 x 1080 | Web images |
150 ppi | 200 KB | 1920 x 1080 | Print images |
300 ppi | 400 KB | 1920 x 1080 | High-quality print images |
600 ppi | 800 KB | 1920 x 1080 | Images for professional printing, such as books, magazines, and brochures |
sharp
The sharp npm package is a good choice for automating image resizing (for example, generating multiple sizes of thumbnails for all the videos on your website). It is fast and easily integrated with build scripts and tools. On the other hand, ImageMagick CLI tool is convenient for one-off image resizing because it is used entirely from the command line.
Node script to convert images using sharp:
const sharp = require("sharp");
const fs = require("fs");
const directory = "./images";
fs.readdirSync(directory).forEach((file) => {
sharp(`${directory}/${file}`)
.resize(200, 100) // width, height
.toFile(`${directory}/${file}-small.jpg`);
});
ImageMagick
can be used to resize images but we need to automate this process which might complicate things:
# To resize an image to 33% of its original size
convert -resize 33% flower.jpg flower-small.jpg
# To resize an image to fit within 300px wide by 200px high
## macOS/Linux
convert flower.jpg -resize 300x200 flower-small.jpg
## Windows
magick convert flower.jpg -resize 300x200 flower-small.jpg
We can also use Responsive Breakpoint Generators like to get different image dimensions:
Lazy Loading
Lazy loading is the strategy of loading resources as they are needed, rather than in advance. This approach frees up resources during the initial page load and avoids loading assets that are never used.
Loading only those image currently present in the view-port.
lazysizes is the most popular library for lazy loading images. It is a script that intelligently loads images as the user moves through the page and prioritizes images that the user will encounter soon.
Steps to integrate lazysizes
:
Add the lazysizes script to your pages:
html<script src="lazysizes.min.js" async></script>
Add
class="lazyload"
and adddata-src
instead ofsrc
to all<img>
and<picture>
tags:- Add the
lazyload
class: This indicates to lazysizes that the image should be lazy loaded. - Change the
src
attribute todata-src
: When it is time to load the image, the lazysizes code sets the imagesrc
attribute using the value from thedata-src
attribute.
html<img data-src="flower.jpg" class="lazyload" alt="" /> or <picture> <source type="image/webp" data-srcset="flower.webp" /> <source type="image/jpeg" data-srcset="flower.jpg" /> <img data-src="flower.jpg" class="lazyload" alt="" /> </picture>
- Add the
- Use Preview Images like single colour SVG's.
- Preview Image
Gulp Tasks
Imagemin
is an excellent image compression tool, it supports a wide variety of image formats and is easily integrated with build scripts and build tools.
We will use gulp-imagemin
plugin for image compression. There are specific imagemin plugins to fine tune the quality of images based on image format. Like:
Image Format | Lossy Plugin(s) | Lossless Plugin(s) |
---|---|---|
JPEG | imagemin-mozjpeg | imagemin-jpegtran |
PNG | imagemin-pngquant | imagemin-optipng |
GIF | imagemin-giflossy | imagemin-gifsicle |
SVG | Imagemin-svgo | |
WebP | imagemin-webp |
const pngquant = require("imagemin-pngquant");
const mozjpeg = require("imagemin-mozjpeg");
const imageminWebp = require("imagemin-webp");
const imagemin = require("gulp-imagemin");
const gulp = require("gulp");
gulp.task("default", () => {
gulp
.src("images/*")
.pipe(
imagemin([
pngquant({ quality: [0.5, 0.5] }),
mozjpeg({ quality: 50 }),
imageminWebp({ quality: 50 }),
]),
)
.pipe(gulp.dest("images/"));
});
JPEG Tools
opj_compress
- Converts
*.pnm, *.pgm, *.ppm, *.pgx, *png, *.bmp, *.tif, *.raw or *.tga
formats intojpeg
.
- Used by
mozjpeg
cjpeg [options] [filename] > [output filename]
- Used by
- Slow
- Based on
libjpeg-turbo
. - Good quality and fast.
- Based on
- All in one image converter
convert [options] [filename]
magick
alias- Other tools