Back

Revelio: Defer and Lazy-Load with the Intersection Observer API

Deloris Thompson
Deloris Thompson
April 8, 2021
Revelio: Defer and Lazy-Load with the Intersection Observer API

Programming, colorful Code on black screen free image download

Deferring and lazy-loading are just a few techniques at our disposal for improving the load speed of a website. One that I am a huge fan of is the Intersection Observer API; we are going to use it to lazy-load a video.

In 2016, Google conducted a research study and found that 53% of mobile users will leave a page that takes longer than 3 seconds to load. Just 3 seconds and your companies competitor could possibly gain a new user.

Intersection Observer API provides a way to asynchronously observe changes in the intersection of a target element with an ancestor element or with a top-level document’s viewport. — Mozilla

Creating an Intersection Observer

The first step is setting the target. This is the child element that is being observed when it interacts with the root (parent).

Next is creating a function; it is called once the page load is finished. The method contains an observer object, options hash, and a call to the observe function provided by the API.

let target = ""; let createObserver = () => { let options = { root: null, rootMargin: '0px', threshold: 0 }; let observer = new IntersectionObserver(callback, options); observer.observe(target); };

Observer: An object set it to a new instance of the Intersection Observer constructor. We pass a reference/pointer to the callback function and the options hash.

Observe: Function provided by the API. Pass the target element you wish to observe here.

Callback Function: Triggered every time a change is observed. Accepts two arguments: the target(s) and the observer.

Options: Optional key/value pairs, defines the behavior. Consists of a root, rootMargin, threshold

Root — This is the parent element or document object. The value must be an element within the DOM tree. The default value is the viewport of the browser.

RootMargin — Margins around the root element that will grow and shrink the container. We set it similar to the CSS margin property. “5px 4px 12px 20px”.

Threshold — The percentage when the object we are observing is intersecting with the container. This will let the observer know when to react. It can be a single value or an array of values

Callback Function

let callback = (entries, observer) => { entries.forEach(entry => { if (entry.isIntersecting) { target.insertAdjacentHTML("beforeend", '<p class="lead"><iframe width="704" height="396" src="<https://www.youtube.com/embed/_JkwZok_GHw>" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></p>') observer.disconnect(); } }); };

isIntersecting: Method provided by the API. True if the target element is intersecting with the root/viewport

insertAdjacentHTML: Attaches the image/video to the target (This is 100% optional, Mozilla and W3 Schools have a lot of methods you can choose from)

disconnect(): Method from the API. Stops watching the target element(s). Use unobserve(entry) if you want to stop observing a single element

Example:

HTML

<div> <div> <h2>Intersection Observer</h2> </div> <div id="intersectionObserverVideo"></div> </div>

JavaScript

let target = ""; window.addEventListener( "load", (event) => { target = document.getElementById("interSectionObserverVideo"); createObserver(); }, false ); let callback = (entries, observer) => { const video = '<p class="lead"><iframe width="100%" src="https://www.yourSource.com/embed/_JkwZok_GHw"></iframe></p>'; entries.forEach((entry) => { if (entry.isIntersecting) { target.insertAdjacentHTML("beforeend", video); observer.disconnect(); } }); }; createObserver = () => { let options = { root: null, rootMargin: "0px", threshold: 0, }; let observer = new IntersectionObserver(callback, options); observer.observe(target); };
Share this post

Interested in working with us?

Give us some details about your project, and our team will be in touch within a day or two.