Lazy Load Images on a Website

Tyler Clark
InstructorTyler Clark
Share this video with your friends

Social Share Links

Send Tweet
Published 6 years ago
Updated 5 years ago

When it comes to websites performance is king. How long it takes for a page to load can mean the difference of millions of dollars for large ecommerce sites. In this lesson we'll use the IntersectionObserver to check when an image is in the viewport to defer loading the image.

Instructor: [00:00] Lazy loading is a technique that defers loading on non-critical resources at page load time. Instead, these resources are loaded at the time of need.

[00:08] When it comes to images, the non-critical images are often the same as off-screen images. Lazy loading images can be accomplished by watching the window scroll or resize events and then calculating when an image is in the viewport.

[00:23] This is the most compatible way of lazy loading images, but there's another way. This can be accomplished via the Intersection Observer API. The Intersection Observer is supported by current versions of Firefox, Chrome, as well as Edge. To get this to work in all other browsers, see the link in the external resources for how to polyfill.

[00:43] First up, let's add an event listener for our DOMContentLoaded event. Once that fires, let's make an array of all of our images that have the lazy class name. Now we need to check that the window has the IntersectionObserver, as well as IntersectionObserverEntry and our intersectionRatio, which lives on the prototype.

[01:12] If it does have that, then inside of this block, we'll do let lazy-image-observer = new-intersection-observer with a function with two arguments, entries and observer. For each entry, we want to check to see if it's intersecting or in the viewport.

[01:27] Then if it is, we want to grab that current entry target and update its source to be the dataset source or update the source set to equal the dataset source set. Then we will remove the class name lazy and then unobserve that current image.

[01:48] To recap what we've done so far, we've created an array of images that all have the lazy class name. Then we've checked the window to make sure that it's compatible. If it is, we've assigned a new-intersection-observer object to lazy-image-observer.

[02:04] This works with each entry which describes an intersection change for one observed target element. If it is intersecting, then we modify the image HTML, swapping out a hypothetical placeholder image with the real source.

[02:21] For each of our images, we actually need to tell our observer what to observe. We're going to for each of our array, and for each one of our images, we're going to use the .observe and pass through our lazy image. This completes the relationship between observers and observes.

[02:37] Our polyfill, we'll just go on the else block here. With the JS part done, when we create our image HTML, we can place a placeholder image in the source, and the real image source inside of our dataset source.

[02:54] You may feel the desire to lazy load all of your images, but keep in mind it's recommended to only lazy load images that lie below the fold, which can be difficult, depending on if you're looking at it on a mobile or a laptop. Do an analysis of your website and see what looks best and works best for you.

Tyler Clark
Tyler Clarkinstructor
~ 6 years ago

Polyfill link: https://github.com/w3c/IntersectionObserver/tree/master/polyfill

JP Erasmus
JP Erasmus
~ 6 years ago

Nice one! Wasn't aware of this technique to lazy-load. 👍 Normally do the scroll event listener + calculating whether the item is partially in the viewport. Do you know how the intersection observer technique compares to the scroll event listener in terms of performance? I've never been a fan of the scroll event listener because it fires so often.

Tyler Clark
Tyler Clarkinstructor
~ 6 years ago

I have not run any tests to measure performance but I would assume that it would be more proformant. As you said, since the scroll event fires a lot as you scroll.

JP Erasmus
JP Erasmus
~ 6 years ago

Thanks for the reply, I'll check it out

Markdown supported.
Become a member to join the discussionEnroll Today