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
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
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
<div> <div> <h2>Intersection Observer</h2> </div> <div id="intersectionObserverVideo"></div> </div>
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); };