Skip to main content
  1. Posts/

Image optimization with Picture tag

One of my friend, struggling with images in his application asked me how I deal with images. I thought it would be a good idea to write a blog about how I personally do it.

I will be writing about static files only or at least image files present on a server that you can install applications and run scripts on. So no images in a database or images that are stored in a cloud storage. For that refer to cloud-flare image optimization or such other services.

Image optimization #

I use ImageMagick to optimize images. So I will be talking about that, again you can use other tools or online webapps to do the same. I convert images to a avif, webp, jpeg format. Most browsers support these formats and they are much smaller than png or jpg formats.

But just in case I also convert them to jpg format. Look at CanIUse for the browser support for avif format. Still not all green.

I use this script to convert images to these formats.

#!/bin/bash
image-opti(){
convert ${1} \
  -strip -write ${1%%.*}.avif \
  -strip -quality 85% -write ${1%%.*}.webp \
  -strip -write ${1%%.*}.jpg \
  -strip -write ${1}
}

Usage being simply image-opti image.png. It outputs image.avif, image.webp, image.jpg and image.png. Optimizing images is the easy part.

Serving images #

It is also the easy part at least if it is for a static website like this one. I use Hugo to generate this website.

By default Hugo has this feature called image processing. This is a very powerful feature that allows you to resize images on the fly and much more, but I don’t use it. I’d rather handle this on my own. As far as i know it does not handle multiple formats.

I simply use HTML picture tag tag to handle image optimization. It is a very simple tag that allows you to specify multiple sources for an image. Whichever one is supported by the browser will be used. That is exactly what I want.

No superpowers needed. Hugo also has this feature called shortcodes. These are like macros but for HTML or markdown files. I created this shortcode to post images with caption in my posts.

<figure>
    <picture class={{.Get "class"}}>
        <source srcset="/img/post/{{.Get "year"}}/{{.Get "src"}}.avif" type="image/avif">
        <source srcset="/img/post/{{.Get "year"}}/{{.Get "src"}}.webp" type="image/webp">
        <img src="/img/post/{{.Get "year"}}/{{.Get "src"}}.jpg" alt="{{.Get "alt"}}">
    </picture>
    <figcaption style="text-align:center">{{.Get "caption"}}</figcaption>
</figure>

Example usage would be

<image class="img-fluid" year="2021" src="image-name" alt="alt text" caption="caption text">

inside a pair of {{}}. Some things are optional here and is necessary for my use case only. I use year to reduce the number of images in a single directory.