Lazy-load iframes

Written by
Published
Updated
Typical Read
5 minutes
Find your next web developer job
Drupal Web Developer at On Fire Media (San Antonio, TX)

Lazy-loading is well-known to decrease load times, improve the UX and boost search engine rankings. An often overlooked opportunity is lazy-loading iframes — learn how.

Lazy-loading resources like JS, CSS, and especially images it first nature for most devs. But did you know you could lazy-load iframes as well — natively? Lazy-load iframes easily, no tricks or hack, with the loading attribute.

Lazy-loading is a massive performance win for web pages. Frontend developers have been doing this for years with JavaScript, CSS, and image files.

An often overlooked lazy-load opportunity is iframes. They’re notorious for slowing down webpages. In this article, we’ll solve that by learning how to lazy-load iframes.

tl;dr

Add a loading="lazy" attribute to the iframe tag that you want to load on demand. The browser will load these when users scroll near the element:

<iframe src="https://www.benmarshall.me" loading="lazy" />

Don’t forget to make your iframes responsive. It’s more important now than ever before. There’s no longer the standard desktop, tablet or mobile screens sizes and why you need to ensure you site & iframes look good on all devices.

Why should you lazy-load iframes?

Lazy-loading iframes are just as important, if not more so, as lazy-loading JavaScript, CSS, and image resources. When lazy-loading isn’t enabled, users pay the cost of downloading data and low Google performance scores.

For instance, it’s no secret that youtube iframe embeds slow down your page load. If you’re not auto-playing the video, ask yourself why are you slowing down your initial page load when you don’t need to?

Based on Chrome’s research, automatically lazy-loading offscreen iframes could lead to 2-3% data savings, 1-2% first contentful paint reductions, and 2% first input delay improvements. When switching to lazy-loading YouTube embeds for Chrome.com, an average of 10 seconds can be saved until our pages could be interactive on mobile devices.

Lazy-loading iframes can also help your Google rank — Google gives preferential treatment to sites that load faster.

How to Lazy-load iframes

What is lazy-loading? Last-loading gives webpages a massive performance boost by yielding priority to other resources that the user may need first. It postpones loading of all lazy-loaded resources until they’re about to come into the browser’s viewport.

iframes have a loading attribute that allows a browser to defer offscreen iframes and images until users scroll near them. This attribute supports three values:

  • lazy: good candidate for lazy-loading
  • eager: not a good candidate for lazy-loading, loads right away
  • auto: the browser determines whether or not to lazily load

The full specification can be found in a pull request on GitHub.

auto is currently a non-standard value, but it the default in Chrome today. Chrome intends on bringing a proposal for this value to the standards table.

Scroll distance threshold

All iframes above the fold (being visible without scrolling) load normally, others are loaded when the user scrolls near them. The distance when elements begin to load is dynamic and depends on:

  • Connection type (e.g. 3g, 4g, unknown)
  • Whether Lite Mode is enabled in Chrome for Android

The distance is chosen so that the deferred content almost always finishes loading by the time it becomes visible. Currently, these values are hardcoded in Chromium’s source and can be overridden using command line arguments.

It may seem like a big issue of the native implementation but actually, it has one substantial advantage – it depends on the effective connection type of user’s device. It would require a lot of work to detect it correctly and we can assume that the values provided by authors of that feature are calculated correctly, so we don’t need to worry about it.

Note: Chrome 77 allows to experiment how different connection types are affecting distance threshold by setting network throttling in DevTools.

The onload event

Lazily loaded image and iframe element’s onload events are triggered – as you might expect – when data is completely loaded. So when the element is lazily loaded, onload fires as a user scrolls near it and the data is fetched.

Document’s onload event works a little bit differently. Traditionally, the event has been fired when all iframes were already loaded. With lazy loading, the document doesn’t wait for deferred, off-screen elements to be loaded before triggering the event.

Browser compatibility

The loading attribute is supported by most popular Chromium-powered browsers (Chrome, Edge, Opera) and Firefox. The implementation for WebKit (Safari) is in progresscaniuse.com has detailed information on cross-browser support. Browsers that do not support the loading attribute simply ignore it without side-effects.

Feature detection

Detecting if the user’s browser supports lazy-loading iframes is easy by checking the loading property defined in the prototypes of HTMLIFrameElement:

if ('loading' in HTMLIFrameElement.prototype) {
  // Native image lazy-loading is available
} else {
  // Use polyfill or a 3rd-party library
}

Native iframe lazy-loading can be applied as a progressive enhancement. Browsers which support loading=lazy on iframes will lazy-load the iframe, while the loading an attribute will be safely ignored in browsers that do not support it yet.

It is also possible to lazy-load offscreen iframes using the lazysizes JavaScript library. This may be desirable if you:

  • require more custom lazy-loading thresholds than what native lazy-loading currently offers
  • wish to offer users a consistent iframe lazy-loading experience across browsers

Check out the example below on how to lazy-load iframes for both legacy and modern browsers:

<iframe class="lazyload" data-src="https://www.benmarshall.me">
</iframe>
if ('loading' in HTMLIFrameElement.prototype) {
  const iframes = document.querySelectorAll('iframe[loading="lazy"]');

  iframes.forEach(iframe => {
    iframe.src = iframe.dataset.src;
  });

} else {
  // Dynamically import the LazySizes library
  const script = document.createElement('script');
  script.src =
    'https://cdnjs.cloudflare.com/ajax/libs/lazysizes/5.2.2/lazysizes.min.js';
  document.body.appendChild(script);
}

loading attribute isn’t just for iframes

The loading attribute can be used for more than just iframes, it works for images too.

This single attribute to perform a complex but useful operation is the ideal solution for lazy loading just about anything. In Chrome 76 onwards, you can use the attribute to lazy-load images without the need to write custom lazy-loading code or use a separate JavaScript library.

Did you find Lazy-load iframes useful? Get articles in your inbox.

…and don’t worry, I hate spam as much as you. Expect to hear from me at most once a week.

Share on facebook
Share on twitter
Share on linkedin
Share on reddit
Share on facebook

Stay updated.

Get a weekly email with the latest trends in web development & SEO.

Write a guest post.

Have an interesting article or idea? Become a guest blogger & pitch me your concept today.

Join the conversation.

Your email address will not be published. Required fields are marked *

All comments posted on 'Lazy-load iframes' are held for moderation and only published when on topic and not rude. Get a gold star if you actually read & follow these rules.

You may write comments in Markdown. This is the best way to post any code, inline like `<div>this</div>` or multiline blocks within triple backtick fences (```) with double new lines before and after.

Want to tell me something privately, like pointing out a typo or stuff like that? Contact Me.