design+
code+
rant

Optimizing Images For Performance

The first version of this website has a bunch of images on its front page. These were not really optimized in any way, and it shows in a performance test:

Testing done with webpagetest.org

Quite squinty, but note the pie-chart: The lilac color is images, while blue and green are HTML and CSS respectively.

Clearly, with 75% of the requests and almost 100% of the bytes spent on images, there is room for improvement.

3.658 secs to first view isn't horrible for a website in general, but should be much better for an otherwise lean blog consisting only of static HTML and CSS.

Existing images used on the front page are png's, weighing in at 1.814 mb total. All are 640 pixels x 480 pixels. One was heavily pixelated for effect, which takes it down to 23kb, while one is black and white, putting it at 171kb. The rest are full color, but rendered from The Gimp at a compression level of 9.

I am no expert on image formats or Gimp rendering algorithms, but scaling down a large jpg (straight from the camera) down to 640 x 480 and rendering a new jpg from The Gimp at 100% quality, results in the image shown at 325kb.

325kb jpg. Yes, it was out of focus to begin with.

Converting that image to png (like the original front-page images) took the size up to 430kb. Later, I'll get into why this happened, but shaving off 100kb simply by choosing the right image type is a good start.

Here follows a bunch of experiments based on anything from vague hunches to almost-knowledge:

Experiment 1: Inlining Image Dimensions in HTML (Half size)

Hypothesis: Adding image dimensions to the HTML results in quicker loading, because browser engines don't have to calculate sizes.

Using the original png files, I tried setting the image dimensions for the front page as inline HTML. First I set them to half their actual size, so:

width="320" height="240"

This resulted in a time to first view at 3.728s - slightly more than before. HTTP requests fell to 66.8% for images and increasing correspondingly for HTML. Bytes downloaded are the same for images.

Just for kicks, I tried repeating the above experiment setting image sizes to full size, so:

width="640" height="480"

First view came in at 3.726s. Ok then.

Results: Poor.

Experiment 2: Rendering Original PNG's as JPG's at Same Size

Hypothesis: JPG's are lighter than PNG's

Having installed ImageMagick as a commandline tool, I navigated to a folder holding the images I wanted to convert, then did this:

magick mogrify -format jpg *.png

This batch-converted all the png's in the target folder to jpg's. Result: File sizes were reduced to about 25% of originals, except for the one which was already 23kb - that got puffed UP to 35kb.

Next, I tried resizing the files to 320x240, since this is really the largest they will get on the site as it is now. I used:

magick mogrify *.jpg -resize 50% *.jpg

It was kind of an experiment with the command syntax (again, not too clear in the docs) and at first, it seemed not to work. But after maybe 20s, I got an output: The files at 50% width/height.

With these two operations, my images went from over 1800kb to 165kb. Functionally, they should work the same as before (no worse).

Boom! First view is now at 0.974s!

Content requests haven't changed much: Images are still at 66.7% of all requests, and down just 2% in bytes. I guess because the page is already so lean in terms of HTML/CSS.

Second test: Below 1 sec now

I have to say, figuring out how to use ImageMagick is a little bit confusing at times. This page states that the "mogrify" command deletes the source files, but doing the format conversion, I didn't find that to be the case, while it did happen after the resizing. Weird, but I make no guarantees it won't delete your files.

Also, apparently you do have to type "magick" before any other command, such as "mogrify", but they don't exactly spell it out on the above-mentioned page...which I only found after a bit of searching (couldn't find a link to it on the ImageMagick front page).

ImageMagick does a lot, but it really could use better docs.

Results: Very good.

Other Things to Try Someday

  • Responsive images (HTML): If I was using lots of large images, I would try this - but haven't yet.

HTML img elements vs. Markdown:

Markdown is nice but sometimes limited, an example of which being the addition of inline HTML element properties. You can render HTML in a markdown file though, but you cannot really properly indent your code, because markdown then thinks you are trying to embed a code snippet - rather than render an actual element. Styling Markdown, then, is tricky...

Resources: