Sunday, January 29, 2023

Best Ways to Preload Images Using JavaScript, CSS and HTML

Best Ways to Preload Images Using JavaScript, CSS and HTML

One of the most important things that you can do to improve the user experience on your website is to make sure that people don't spend their time waiting for some image or other element to load.

How quickly a webpage and all its contents load depends on a large number of factors and some of them will be beyond your control. However, we should try our best as web developers to make the browsing experience as seamless as possible.

In this tutorial, I will show you different techniques to preload images on a webpage for a smooth user experience.

The Need for Preloading Images

We will begin the tutorial by first discussing why you might need to preload images.

Let's say you are building a portfolio website for a real estate agent where they can showcase houses for sale. The agent wants you to show a list of houses with an image of the exterior of the houses. They also want you to design the page in such a way that hovering over a house image loads another image of the interior of the house with a link to see all other images.

The problem here is that the image of the interior of the house will only start loading when users hover over the image. This means that they will not see any image for a few moments after the initial hover event depending on their internet speed. You can see this problem in the following CodePen demo:

Preloading the images will avoid this delay in image load on hover. Also, some large images might take a while to load so it is better to preload them for a better user experience.

Preloading Images Using HTML

You are most probably already familiar with the link tag in HTML. We generally use it to load an external CSS stylesheet but you can also use it to load other type of resources as well. There are two important attributes of the link tag.

The href attribute which is used to provide the path to the resource that we want to fetch and the rel attribute which specifies the relationship of the resource with the containing document. With a CSS stylesheet, the link tag looks like this:

1
<link rel="stylesheet" href="navigation.css" />

The rel attribute can take a lot of valid values. One of them is preload which we will use to preload our images. The preload attribute tells the browser to preemptively fetch and cache the linked resource as it will be needed on the current page.

You also need the as attribute when the value of rel attribute is set to preload. This will specify the type of content that is being loaded by the link tag. This attribute serves many important purposes such as applying the correct content security policy, prioritization of the request etc. Skipping it could prevent your image from being preloaded.

We will load our image in the following div element:

1
<div class="hover-me"></div>

Then apply the following CSS to the div element. As you can see, the background image URL changes whenever someone hovers over the div element.

1
div.hover-me {
2
  width: 640px;
3
  height: 360px;
4
  background: url("https://picsum.photos/id/128/1920/1080");
5
  background-size: contain;
6
  cursor: pointer;
7
  margin: 0 auto;
8
  position: relative;
9
}
10
11
div.hover-me::before {
12
  content: "Lake";
13
  background: black;
14
  color: white;
15
  position: absolute;
16
  top: 0.75rem;
17
  left: 1rem;
18
  padding: 0.5rem;
19
  font-size: 1.5rem;
20
  border-radius: 5px;
21
}
22
23
div.hover-me:hover {
24
  background: url("https://picsum.photos/id/296/1920/1080");
25
  background-size: contain;
26
}
27
28
div.hover-me:hover::before {
29
  content: "Mountains";
30
}

The image that shows up when we hover over the div element is preloaded by using the following markup. You should ideally place the link tag inside the head tag of your webpage.

1
<link rel="preload" as="image" href="https://picsum.photos/id/296/1920/1080" />

The following CodePen demo shows the image preloading in action:

Preloading Images Using CSS

You might have noticed in the previous section that both the images we used were actually applied as a background to the div element. However, only one of them was downloaded by the browser. The image that was applied as background on hover was downloaded only after the hover event occurred.

In the previous section, we forced the hover image to download with the help of HTML. However, we could also trick the browser in downloading the hover image by applying it as a background image to some other element on the webpage. Another option involves setting the image URL as a value of the content property.

I prefer to use the body element along with the ::before or ::after pseudo-elements. The URLs that I want to download will be set as a value of the content property of any of the pseudo-elements.

One important thing to keep in mind here is that we need to push the pseudo-elements far off the screen to prevent their contents from accidentally appearing on the screen. The following CSS takes care of all this for us:

1
body::before {
2
  content: url("https://picsum.photos/id/296/1920/1080");
3
  position: absolute;
4
  top: -9999rem;
5
  left: -9999rem;
6
  opacity: 0;
7
}

I have also set the opacity to 0 as a precautionary measure. Do keep in mind that you shouldn't set the display property to none to hide the element. In that case, the browser is much more likely to not download the image at all.

You can see that the image we need on hover is preloaded in the following CodePen demo:

Preloading Images Using JavaScript

It is also possible to preload images using JavaScript. This method gives you the most control over the way you preload the images. Preloading images using JavaScript is also more convenient in situations where you have to load a large number of images. However, it will only work if JavaScript execution isn't disabled in the browser.

The following function can help us preload any image in JavaScript.

1
function preload_image(im_url) {
2
  let img = new Image();
3
  img.src = im_url;
4
}

The function accepts the path to an image you want to preload as a parameter. Inside the function, we use the image constructor to create a new instance of HTMLImageElement. After creating the image element instance, we set the value of its src property to path of the image we want to preload.

All that's needed now is a call to the preload_image() function as shown below:

1
preload_image("https://picsum.photos/id/296/1920/1080");

You can see the JavaScript image preloading in action in the following CodePen demo:

Final Thoughts

In this tutorial, we learned about three different techniques to preload images. Using the link tag in HTML allows us to start loading images as early as possible. On the other hand, it is much more convenient to use JavaScript when you want to preload multiple images. You can also control the order in which images are preloaded with JavaScript. This way we can make sure that image preloading doesn't block the main content from loading first.


No comments:

Post a Comment