How I Lost (Page) Weight and Kept It Off

I heard if you can keep an image-heavy page under 5MB, it’s better than eating Açai berries. But seriously, with three lines of code, I was able to translate a 19.2 MB webpage to 4.7MB

TL;DR; Using Google Chrome Developer Tools and an image processing tool, I optimized image galleries on my game sharing website by about 75%. This reduced the overall bounce rate on my site by 21%.

Setup

Let’s start off with my problem – I have lots of user-generated images of varying size and resolution on my website. They loaded horribly after more and more were added.

The front page shows users a gallery of games and tries to entice them to play one or two of them before leaving the site.

There’s a mystifying number of games on the front page, but to keep things clean, I’ll be using a simplified version of my game gallery available at this CodePen.

I have an HTML container field:

<div id="container">
</div>

And some javascript to render images:

const urls = [
  '/screens/1.png',
  '/screens/2.png'
  //...many more urls here
];

let imgHTML = '';

urls.forEach(url => {
  imgHTML += `<img class="img" src="${url}"/>`;
});

document.querySelector('#container').innerHTML = imgHTML;

I also have a little bit of CSS to resize the images and make them stack nicely.

See it at https://codepen.io/Filestack/pen/orVJmd

My Big Fat Page

I open Google Chrome developer tools (Mac: ⌘+⌥+I Win: CTRL+Shift+I) and switch to the network panel:

Then I refresh the page, and notice that the total page weight is a whopping 19.2MB! This would be terrible on a mobile browser, and barely passable on a desktop browser!

The Obvious Problem

The more obvious problem is that our css renders images of varying sizes at just 200px tall:

.img {
  max-height: 200px;
  float: left;
}

I can confirm this by switching to the Elements panel in devtools, and highlighting one of our image divs:

As you can see, the rendered size is just 266X200 pixels, while our intrinsic (downloaded) size is 960×720 pixels.

Some back of the napkin math (jk, I used a calculator):

960*720 = 691200 // size of downloaded

266*200 = 53200 // size of displayed

69120 / 53200 = 12.992

We could be serving an image that’s approximately 1/13th the size (in pixels), and the website visitor would have just the same impact.

Solutions to the Obvious Problem

There are two things we could do here:

  1. I could manually resize these images to the correct pixel height.
  2. I could write a backend service using ImageMagick or similar to resize the image before serving it.

#1 is no good. I’m a programmer! I abhor repetitive work! And #2 sounds like one-to-six weeks of backend code. While fun, in theory, my PM says hell no!

Manually resizing also has another disadvantage–these images are presumably user generated–that is, people who upload games to my site also upload a screenshot. I’m definitely not down for resizing an image at 3:45AM Pacific time when a user from Indonesia uploads a game.

Ready to get started?

Create an account now!

The Glorious Plan C

Since Plan A and B were not ideal, I started searching for on-the-fly services that would translate my images to a smaller size with little or no work.

I found Filestack’s image processing API which was phenomenal at doing this, with no backend work on my part. So I signed up for a free API key to test it out.

It turns out that that backend resizing is really simple with Filestack. All I needed to do was construct a URL on the frontend and Filestack would do the rest. Here’s the structure:

https://cdn.filestackcontent.com/<api_key>/<transformations>/<original_url>

So in my case, here are the params I used:

api_key: Get a free one free here!

transformations: resize=height:200

Original URL: https://simmercdn.com/unity/pPVDbVGZKBZigDHHe4WDzukkekh2/content/fcca762b-ee84-f0af-07b2-9e706a25c013/screens/5.png

This gave me a final URL that looks like this:

https://cdn.filestackcontent.com/GET_AN_API_KEY_FROM_FILESTACK/resize=height:200/https://simmercdn.com/unity/pPVDbVGZKBZigDHHe4WDzukkekh2/content/fcca762b-ee84-f0af-07b2-9e706a25c013/screens/5.png

Which creates a perfectly sized image that looks like this at full pixel size:

 

Perfect for my site!

Pro Tip: There are lots of other cool ways to transform your image–like adding a border or sepia tone. There’s some pretty awesome photoshop-esque filters in the Filestack dashboard that you can call on the fly, just like I did with the resize above!

A Cool Bonus

If you’re running a static website from a non-cloud provider, your site will be likely be served from a particular location (let’s just say Missouri, USA). Filestack uses a CDN which ensures that your images will be cached close to where your users live.

For instance, if you’re hosting in Missouri and a user from the UK requests an image from your server, the next person close to the UK that requests your image will also get an image served from the UK.

This saves precious milliseconds and keeps people from hitting “back” before your site loads.

My New (Page) Weight

First, let’s look at the code needed to change our image URL’s into Filestack transformations:

const FILESTACK_BASE = 'https://cdn.filestackcontent.com';
const API_KEY = 'FILESTACK API KEY';
const TRANSFORMATION = 'resize=height:200';

urls.forEach(url => {
  const filestackUrl = [FILESTACK_BASE, API_KEY, TRANSFORMATION, url].join('/');
  imgHTML += `<img class="img" src="${filestackUrl}">`;
});

This ensures that our files are no larger than 200 pixels tall when served. See CodePen for this stage of the project.

Let’s also check out our total page weight (Chrome Developer Tools => Network Panel => Refresh Page).

 

With just about three lines of code we’ve already lowered our page weight from 19.2MB to 6.7MB, a savings of almost 300%.

Let’s Not Stop There

Let’s not quit here. There’s still work we can do to get this image gallery thousands of kilobytes smaller. Stay tuned for the next update where I’ll explain profiling with Google Audits / Lighthouse. I’ll also describe how I used CSS to make these images look beautiful on a dark background with light text:

 

Want to get started eliminating page weight of your own? Sign up for free with Filestack today!

Read More →