‹ Back to writing

A friend recently sent me some info about an interesting encoding option for images while I was looking into the difference between PNGs and JPEGs. I ended up using it to fix (well, improve) a performance problem with my site, so I thought I’d do a short writeup about it!

The problem

You’ve built a website with a bunch of beautiful PNGs in it, and everything looks great! You deploy and go check out the site, and:

A PNG on my personal site loading very slowly

Wait for it…wait for it…

Not ideal. Especially for users on a slow connection (this example is using “Slow 3G” throttling in Chrome to highlight the issue). There are a few seconds there where they might not even know more content is still loading in. Is there a way to give them something to work with in the meantime?

The solution

Converting those sluggish PNGs to more performant JPEGs should clear this up. But, any old JPEG won’t do; we’ll be converting our PNGs to ✨ Progressive JPEGs ✨.

In short, Progressive JPEGs render differently than normal JPEGs. Both are still processed by the browser line-by-line, but a Progressive JPEG will generate a lower-res “placeholder image” as it loads and then do another pass over the image while it finishes processing. This way, users can see that something is loading sooner, improving the overall UX.

So, how do we actually convert our PNGs? Well, one quick way is to use the Node package sharp. The snippet below lets us take in a PNG’s filepath, use the jpeg method with the progressive: true option to convert the image to a Progressive JPEG, and then write that to a new file.

sharp(inputPath)
    .jpeg({progressive: true})
    .toFile(outputPath);

After we swap out the old image for the converted one, here’s what we get:

The converted PNG from earlier loading more quickly

Progress!

In the same conditions, the PNG version of the image takes ~10.3s to finish loading vs ~6.3s with the Progressive JPEG! So, not only do users get to start seeing content quicker because of the Progressive rendering, but the user gets their content faster since we’re not using bulky PNGs anymore.

For comparison, here are both images loading at the same time. The original PNG is on top, while the JPEG is on the bottom.

Both image formats loading at the same time

Low-lift improvements like this leave your site feeling lightning-fast to your users! Kachow.