I have recently seen a number of recommendations for using progressive JPGs for improved perceived image loading performance. Additionally, I recently learned about chroma subsampling and decided that I wanted to try deploying images on my site as progressive JPGs with a 4:2:0 chroma subsampling.

Currently, all images on my site are PNGs. I like the level of lossless compression that you can get with PNG, as well as the ability to have an alpha channel. That said, I wanted to experiment with serving different types of images and looked into converting my PNGs to progressive JPGs.

After some searching, I found Imagemagick’s convert CLI was a great option for easily converting PNGs to progressive JPGs. I used the following command to handle the batch conversion, which was adapted from Andrew Walker’s Coderwall post:

for i in /path/to/site/media/images/*.png; do
  convert \
    -strip \
    -interlace plane \
    -background "#F8F8F8" \
    -alpha remove \
    -flatten \
    -quality 80 \
    $i $(echo $i | sed 's/png/jpg/g'); \
done

It took a little finagling to get this right. A few important notes:

  • The interlace argument turns the image into a progressive JPG (or an interlaced PNG if we were making an PNG). The two primary value for this argument seem to be plane or line. I could not find a definitive answer for what the differences between the two were, so I just used plane as Andrew recommended.
  • Without specifying a color for the background argument, my images with transparency turned to a black background. I gave them a color of #F8F8F8 to match my site’s background color. Additionally, -alpha remove was necessary to remove the alpha channel and get the correct background color.
  • Convert’s default chroma subsampling is 4:2:0, which seems to be the recommended standard; however, in some documentation, it seems like this is only applied if the JPG quality is less than 90.

After deploying these changes, I have seen no measurable performance difference; however, that was not expected. The primary reason for this change is to improve perceived performance, in that the image should theoretically be partially painted to the screen more quickly, giving the perception of faster performance. Interestingly, some of the image sizes were bigger after the conversion, which I suppose makes sense given the compressibility of PNGs.

References: