Lazy Loading Image Dimensions

Chapter 4 7 mins

Learning outcomes:

  1. The problem of reflow
  2. Giving dimensions to images
  3. Retrieving the natural dimensions of images

Reflows are bad!

If you noticed one thing in the Simple Lazy Loader made in the previous chapter, as the lazy image loaded into view it caused a page reflow i.e made the document to change its layout.

This is bad!

For example, if there is some text that the user is reading below the image, lazy loading in this way would cause the content to move downwards, (once the image loads), and consequently interrupt the user's reading.

Although we do see such types of lazy loaders around the net, this is an example of bad programming, developers must avoid. So how to avoid the reflow of the page once we load an image into view? This is all what this chapter is about.

A width and height

Perhaps the easiest solution to avoid page reflow, which comes to the mind first, is to give custom dimensions to the image.

In this way the image will already have a predefined area to fit into once it gets loaded and as a result prevent the need to reflow the page.

But before we can set custom dimensions on an image, we first need to know them. This can be done in one of the following ways:

Why?

Well, essentially, it all boils down to our choice — we can give the lazy image any dimensions we like and get it to fit anyhow.

For instance, we can do the following for every image on a web page:

.lazy_img {
    width: 100%;
    height: 300px;
}

Each image would fill all the available width of its parent, along with having a height of 300px.

This would work perfectly as long as the image is roughly equal in proportion and size to the given dimensions, above.

However, if the image doesn't meet these conditions — let's say, it's relatively too small with a low resolution or of a larger height as compared to its width — then the final result might break the image's natural proportions and look extremely pathetic!

Seriously.

Try altering the proportions of an image by changing only its height or changing only its width at a time. You'll see how the image would be looking like a piece of junk!

What we need are the natural dimensions of the image.

The natural dimensions are the default dimensions of an image, without any sort of custom resizing applied on it.
Add an image to a blank HTML page. Its dimensions there are its natural dimensions.

Once we have the natural dimensions in hand, we can apply them on the image to give it a fixed space where it would be displayed, thus avoiding any page reflows in the future.

Below we restrict the width and height of an image based on its natural dimensions:

<div class="lazy"><img class="lazy_img" data-src="image.png" width="320" height="640"></div>

In this case, we knew the natural dimensions of the image so it was fairly straightforward to apply them on it and move on. However, often times while adding an image to the HTML, we are unaware of them.

In these cases, it's required to first find the dimensions using one of the ways discussed below.

Getting the natural dimensions

There are mainly two ways to retrieve the natural dimensions of an image.

One is to perform this on the frontend by manual methods, whereas the other is to perform this on the backend.

Both of these ways are discussed thoroughly below.

Frontend solution

On the frontend, we start by loading an image (not lazy load) on a blank HTML page and then get its dimensions using either:

  1. Developer Tools
  2. JavaScript

Let's consider each one...

Using the Developer Tools

Go ahead and open the following link on your browser and then inspect the displayed image in the developer tools area.

HTML page with image

  1. Right-click the image, and then select Inspect Element. This opens up developer tools.
  2. Head over to the Computed tab, in the pane where the CSS styles of the image are displayed.
  3. In the Computed tab, notice the dimensions of the image in the box model.
Console's computed styles

Note these down and put them in your HTML — inside .lazy_img.

Following is an example:

<div class="lazy"><img class="lazy_img" data-src="image.png" width="320" height="640"></div>

Some JavaScript

Apart from using developer tools, we can also inspect the dimensions of an image using JavaScript.

In particular, we can attach a load listener to the image, that prints its natural dimensions using the naturalWidth and naturalHeight DOM properties.

<img src="imageWithUnknownDimensions.png" onload="console.log(this.naturalWidth, this.naturalHeight)">

The code here simply alerts the width and height of the <img> element, which can be copied and then pasted in the lazy image's markup.

Following is a live example.

Live Example

As an exercise, and a tough one, you can make an HTML form to select an image from your local file system, and then use FileReader() to read it into the document and finally bring into the game naturalWidth and naturalHeight.

Backend solution

If you don't want to go through this manual, arguably tiring, work, then you can use a backend language to get the dimensions of an image right away as you write the markup for it in your code editor.

We will demonstrate an example in PHP. You can go with any backend language you like given that it has some predefined mechanism to retrieve the dimensions of an image.

Consider the code below:

<?php
    function getDim($src) {
        $size = getimagesize($src);
        echo 'width="' . $size[0] . '" height="' . $size[1] . '"';
    }
?>

We have constructed a function getDim() which takes an image's source URL $src and prints a string with its dimensions. The string is layed out such that it can be inlined directly within the markup of the .lazy_img.

<div class="lazy"><img class="lazy_img" data-src="image.png" <?php getDim("image.png"); ?>></div>

Absolute Dimensions Lazy Loader