Resizing images on upload VS Resizing images on the fly

In this article, we are going to look at why resizing images on upload is better than dynamically resizing them “on the fly”.

To make a long story short, static images will always be faster than dynamically-generated images.

Resizing the image on upload.

Using this method, we resize the image as soon as it reaches our server.

This way, we don’t have to worry about resizing it at a later date.

A basic drilldown of this process:

  1. The user uploads an image.
  2. Our code resizes and crops the image to various different sizes.
  3. We store the file path in our database.

image references stored inside the database

As you can see in the example above, we are storing two different versions of our uploaded image: The original and the resized thumbnail.

This means that we can easily display our thumbnail images like so:

//Get the last ten images that were uploaded.
$sql = "SELECT `id`, `thumbnail` FROM `images` ORDER BY `created` DESC LIMIT 10";
$statement = $pdo->prepare($sql);
$statement->execute();

while ($row = $statement->fetch(PDO::FETCH_ASSOC)) {
    $thumbnailUrl = 'img/' . $row['thumbnail']; ?>
    <img src="<?php echo $thumbnailUrl; ?>">
    <?php
}

Resizing images on the fly.

Dynamically resizing images involves the following:

  1. The user uploads an image.
  2. Our code doesn’t modify the image. Instead, we just save it as it is.
  3. Later on, when we are displaying the image, we pass the URL of the original to our “resizer” script, which resizes it down to a specified size.
  4. Our resizer script should then cache the generated thumbnail on disk for future use.

An example of what the code might look like:

//Get the last ten images that were uploaded.
$sql = "SELECT `id`, `url` FROM `images` ORDER BY `created` DESC LIMIT 10";
$statement = $pdo->prepare($sql);
$statement->execute();

while ($row = $statement->fetch(PDO::FETCH_ASSOC)) {
    $url = 'img/' . $row['url']; ?>
    <img src="library/resizer.php?img=<?php echo $url; ?>&w=120&h=120">
    <?php
}

Which method is better?

In my opinion, the resize-on-upload solution is better.

  1. It doesn’t force random visitors to bear the brunt of image processing. A user who is uploading something will obviously expect a slight delay, so that’s OK.
  2. If we need to, we can add the resize job to a queue.
  3. Disk space is cheap. Image processing? Not so much! For example, in the past, I’ve witnessed 2MB pictures taking up to 0:00.15s in CPU processing time. That’s 0:00.15s per photo! What if you have a gallery and you need to create 20 thumbnails on the fly?
  4. If the cache fails for whatever reason (or if it doesn’t exist), dynamically generating thumbnails will become a painful experience for both the server and the end-user. A while back, I remember someone on Stackoverflow referring to it as a self-inflicted DoS attack (obviously, the extent of the damage will depend on how many visitors you typically see, which is why so many “Mom & Pop” websites get away with not caching).
  5. If, for whatever reason, you need to change the thumbnail dimensions, you still have the original on file.