www 101

All you need to know about the internet

Have a Question?

If you have any question you can ask below or enter what you are looking for!

Performance Enhancement: How to Load Images Using in-view.js

In this tutorial I’ll show you how to improve the performance of your web pages by using in-view.js. This JavaScript library reports back when something has scrolled into the viewport and will help us dynamically load our images as they’re needed.

Performance Matters

Web performance matters, especially if your website targets developing countries where connections are slow and data plans are expensive. A few basic tasks we commonly undertake to improve our websites’ performance include minifying JavaScript files and stylesheets, “gzipping” assets, compressing image sizes, after which we’re pretty much all set. But are we?

Page load time and the browser inspector timeline

The above inspector example shows a single page loading 24 images in a mobile-size viewport at regular 3G-speed. And as we can see, the page load is complete at around eleven seconds! This is really slow given that we’re dealing with a simple page with nothing but a few images and a stylesheet. The page is not yet polluted with ads, nor tracking scripts which usually add further ballast to the page. 

Also worth bearing in mind, is that this is merely an emulation. It doesn’t even take into account the server setup, latency, and other technical hurdles. The performance could be meven worse in reality.

So how can we improve the page load performance?

Bottleneck

First up, we have a number of images. The reason our page loads slowly is because all the images are flooding in together upon initial page load. If you take a closer look at the the previous image, you’ll see this doesn’t happen in parallel: a couple of images only begin loading once others are being rendered, which bogs the page down as a whole.

If we have a large number of images on a single page, we can consider loading these images asynchronously and only when the user needs them. This enables the browser to complete loading the viewable page without needing to wait for all the images to be rendered, ultimately saving the user bandwidth.

Getting Started

To follow along, grab the index-starter.html from the repo. There’s also an accompanying css/styles-starter.css which you can use too.

To begin with, we need to replace the image sources with a really small image, preferably encoded into base64 to avoid any extra HTTP requests. We use this image as a placeholder before we serve the actual image. That being said, we must also store the actual image source in a custom attribute named data-src.

Once you have done this and refreshed the page, you should find the images are currently blank and their dimensions are not necessarily what your final images should have.

Chrome Browser Window with square blank image

So let’s fix the styles.

Retaining the Image Ratio

The images we want to use are set at 800 by 550 pixels. We’ll divide the image height (800px) by the image width (500px), and multiply this by 100%. Use the result to set the padding top of the pseudo-element of the image container. Lastly, we need to set the image position to absolute and set the maximum height to 100%, so it won’t bolster the height.

At this point, the image dimensions should be correct. However, the real image source still resides in a custom attribute so the browser can’t actually fetch any images yet.

Image is at its appropriate ratio, but the image is yet loaded.

Our next step will be adding some JavaScript that will load the image.

Get the Image Loaded

Firstly, we need to load in-view.js to the page. As mentioned, this lightweight library (which is not dependant on jQuery or a core library like Waypoints) detects whether an element is inside or outside the browser viewport. 

Now create a new JavaScript file where we will write our JavaScript and load it after in-view.js, as follows:

Methods and Functions

The in-view.js library exposes the inView() function which takes a selector as the argument. In this case, we will pass the figure element; the element that wraps the images. The reason we select the wrapper element is because we are going to add a couple of classes to perform style transitions–this is more easily done when the class is on the wrapper element rather than the image itself, hence:

Next, we use the .on() method to bind the element with the enter event to check whether the element is within the viewport. In addition, in-view.js also exposes the exit event which does the opposite; this detects when the element is out of the viewport.

The enter event will trigger a function, which will does the following:

  1. Select the image within the figure.
  2. Make sure that it has the data-src attribute.
  3. Add is-loading to the wrapper, figure, element.
  4. Load a new image with the source retrieved from the data-src attribute.
  5. Once loaded add the image to the container.
  6. And lastly, replace the is-loading class with the is-loaded class.

We Wanna Get Loaded

As you can see from the above code, we have introduced two new classes is-loading, and is-loaded. We use the is-loading class to add a spinner animation while the image is loading. We then use the is-loaded class, as the name implies, to add the transition effect to the image when the image has been completely loaded.

Fallback

Hope for the best, but plan for the worst. So just in case JavaScript is somehow disabled (a rare case, but perfectly possible) we need to ensure the image will still be displayed. Use the <noscript> element with the image source immediately pointing to the real image source.

We are all set! Refresh the page, and if we inspect the network timeline in DevTools we can see the page speed is now significantly improved since we’re only loading what’s visible to the users.

Faster!

The page load is now complete in only 1.95s at regular 3G-speed; more than a 500% speed improvement!

Wrapping Up

In this tutorial, we looked at how to improve page load by rendering images only when the user sees them. This method is popularly known as “lazy loading” and it can help your website performance enormously. 

There are many JavaScript libraries and jQuery plugins which do this, so why opt for in-view.js? Personally, in-view.js has been the kind of script I’ve been looking for since it doesn’t try to do too much. It only handles one thing and does it well. This kind of library gives more control and greater flexibility.

For instance, not only can we can use in-view.js to perform lazy loading, but we can also use it for things such as performing infinite scroll, perhaps displaying a floating subscribe form when the user reaches the end of the page (take a look at the demo to see that in action), or creating a vertical timeline without having to pull in yet another JavaScript library. Let us know how you use it!

floating subscribe form
Floating subscribe form, animated into view once the user reaches the end of the page

Further Resources