Defer YouTube Loading until Scrolled-To (Lazy-Loading)
A demo that combines my Add Class to Target-Element when Trigger-Element is Scrolled into View elementFromTop() JavaScript function with some other fluff, to automate Thoriq Firdaus' How to "Lazy Load" Embedded YouTube Videos script and stop YouTube placeholder resources from loading until each video embed is scrolled-to.
Works in modern browsers and IE9+
Please view the source of this page for HTML, CSS and JS.
Scroll Down...
There are 10 YouTube video embeds below. The page markup is made up of the default iframe embed code, which would normally load-in a heap of additional resources from YouTube (see the test case with only default iframe embeds).
How It Works
The stripYouTubeEmbed() JavaScript function in this demo strips out the iframes, before any additional resources get chance to load, and replaces them with wrapper divs holding a "youtube" class, and a "data-embed" attribute containing the YouTube video ID, derived from the iframe's original "src".
<div class="youtube-wrap">
<div class="youtube" data-embed="leVxy7cjZMU">
<div class="youtube-play"></div>
</div>
</div>
Next, the "youtube" class is passed to the elementFromTop() JavaScript function, which adds a "yt-load" class when the scroll distance is met.
<div class="youtube-wrap">
<div class="youtube yt-load" data-embed="leVxy7cjZMU">
<div class="youtube-play"></div>
</div>
</div>
The LazyLoadYouTubeEmbed() function (adapted from Thoriq Firdaus' How to "Lazy Load" Embedded YouTube Videos script) then kicks in, looking for elements with this "yt-load" class, and the "data-embed" attribute, to load in the associated placeholder image from YouTube.
<div class="youtube-wrap">
<div class="youtube yt-load" data-embed="leVxy7cjZMU">
<div class="youtube-play"></div>
<img src="https://img.youtube.com/vi/leVxy7cjZMU/sddefault.jpg">
</div>
</div>
The previously stripped iframe code is returned, and replaces the placeholder image when clicked.
<div class="youtube-wrap">
<div class="youtube yt-loaded yt-load" data-embed="leVxy7cjZMU">
<iframe frameborder="0" allowfullscreen="" src="https://www.youtube.com/embed/leVxy7cjZMU?rel=0&showinfo=0&autoplay=1"></iframe>
</div>
</div>
The last thing the LazyLoadYouTubeEmbed() function does is add a "yt-loaded" class, which it uses to exclude a video embed from the next round of executions.
JavaScript Performance Considerations
Because this is a scroll-activated script, the rate at which the function fires has the potential to be very high.
Attaching functions directly to the scroll event is usually a bad idea; Scrolling using a trackpad, scroll wheel, or just by dragging a scrollbar can easily trigger 30 events per second. Scrolling on a smartphone can trigger significantly more.
This script takes performance into consideration by using;
- A throttle to limit how often the elementFromTop() function executes while scrolling.
- A debounce to recalculate window height and fire the elementFromTop() function after a window resize event.
"Debouncing" and "throttling" help improve performance by controlling the effect of potentially expensive JavaScript functions that may otherwise cause a page to become unresponsive when fired repeatedly. Please see the Debouncing and Throttling Explained Through Examples article at CSS Tricks for further information.
Related
More demos and snippets
Did you find this useful? There are more demos and code snippets this way.