Native browser-level lazy loading for iframes is here
The native lazy loading for landed images in Chrome 76 via loading
attribute and then it came to Firefox. We are happy to share that
native lazy loading for iframes is now
standardized and it is also compatible with Chrome and Chromium browsers.
<iframe src="https://example.com"
loading="lazy"
width="600"
height="400"></iframe>
Native iframe lazy loading defer loading iframes off-screen until the user scrolls close to them. This saves data, speeds up the loading of other parts of the page, and reduces memory usage.
Is manifestation from
shows lazy loading video embeds:
Why should we lazily load iframes?
Third-party embeds cover a wide range of use cases, from video players to social media posts and ads. Often times, this content is not immediately visible in the user viewport. Rather, it is only seen once they scroll down the page. Despite this, users pay the cost of downloading data and expensive JavaScript for each frame, even if they don't scroll to it.
Based on Chrome's research on iframes off screen lazy loading automatically for Data Saver users, lazy loading iframes could result in average data savings of 2-3%, first paint reductions with 1-2% content in the median, and 2% improvements in first entry delay (FID) at the 95th percentile .
How does native lazy loading work for iframes?
the loading
The attribute allows a browser to defer the loading of iframes and images off the screen until users scroll close to them. loading
supports three values:
lazy
: is a good candidate for lazy loading.eager
: not a good candidate for lazy loading. Charge immediately.car
: the browser will determine if it loads lazy.
car
It is currently a non-standard value, but it is the default in Chrome today. Chrome intends to bring a proposition of this value to the standards table.
Using the loading
attribute in iframes works as follows:
<iframe src="https://example.com"
loading="lazy"
width="600"
height="400"></iframe>
<iframe src="https://example.com"
width="600"
height="400"></iframe>
<iframe src="https://example.com"
loading="eager"
width="600"
height="400"></iframe>
Not specifying the attribute at all will have the same impact as explicitly loading the resource with enthusiasm, except for The light mode
users, where Chrome will use the car
value to decide if it should be lazy loaded.
If you need it dynamically create iframes via JavaScript, setting
iframe.loading = 'lazy'
in the element is also
supported:
var iframe = document.createElement('iframe');
iframe.src = 'https://example.com';
iframe.loading = 'lazy';
document.body.appendChild(iframe);
Iframe specific lazy loading behavior
The load attribute affects iframes differently than images, depending on whether the iframe is hidden. (Hidden iframes are often used for analytical or communication purposes.) Chrome uses the following criteria to determine if an iframe is hidden:
- The width and height of the iframe are
4px
or less. display: none
orvisibility: hidden
It is applied.- The iframe is positioned off screen using negative X or Y positioning.
- This criterion applies to both
loading = lazy
andloading = auto
.
If an iframe meets any of these conditions, Chrome considers it hidden and will not lazy load it in most cases. Iframes that are not hidden will only load when they are within the loading distance threshold. Chrome shows a placeholder for lazy-loaded iframes that are still retrieving.
What impact could we see in popular lazy-loading iframe embeds?
What if we could change the web in general so that the lazy loading screen iframes were the default? It would look a bit like this:
Lazy Loading YouTube Video Embeds (saves ~ 500KB on initial page load):
<iframe src="https://www.youtube.com/embed/YJGCZCaIZkQ"
loading="lazy"
width="560"
height="315"
frameborder="0"
allow="accelerometer; autoplay;
encrypted-media; gyroscope;
picture-in-picture"
allowfullscreen></iframe>
Anecdote: When we switched to lazy loading YouTube embeds for Chrome.com, we saved 10 seconds from how quickly our pages could be interactive on mobile devices. I opened an internal error with YouTube to discuss how to add
loading = lazy
to your embed code.
If you are looking for more efficient ways to upload YouTube embeds, you may be interested in the YouTube lite component.
Lazy loading Instagram inserts (saves> 100KB in gzip on initial load):
Instagram embeds provide a markup block and script, which injects an iframe into your page. Lazy loading this iframe avoids having to load all the script required for the insert. Since such embeds are often shown below the viewport in most articles, this seems like a reasonable candidate for native lazy loading of your iframe.
Lazy Loading Spotify Embeds (saves 514KB on initial load):
<iframe src="https://open.spotify.com/embed/album/1DFixLWuPkv3KT3TnV35m3"
loading="lazy"
width="300"
height="380"
frameborder="0"
allowtransparency="true"
allow="encrypted-media"></iframe>
Although the embeds above illustrate the potential benefits of lazy-loading iframes for media content, there is a chance to see these benefits in ads as well.
Case Study: Native Lazy Loading of Facebook Social Plugins
From Facebook social plugins Allow developers to embed Facebook content on their web pages. Several of these plugins are offered, such as embedded posts, photos, videos, comments ... The most popular is the As a complement - a button that shows a count of who has 'liked' the page. By default, embedding the Like plugin on a web page (using the FB JSSDK) pulls ~ 215KB of resources, 197KB of which is JavaScript. In many cases, the plugin may appear at the end of an article or near the bottom of a page, so enthusiastically loading it when off-screen may not be optimal.
Thanks to engineer Stoyan Stefanov, all facebook social plugins now support native iframe lazy loading. Developers opting for lazy loading via plugins data-lazy
The settings will now be able to prevent loading until the user scrolls nearby. This allows embedding to continue to work fully for users who need it, while offering data savings for those who don't scroll down a page. Hopefully this is the first of many additions to exploring native iframe lazy loading in production.
Wait, can't browsers just auto load off-screen iframes lazily?
They certainly can. In Chrome 77, Chrome added support for off-screen images and lazy loading iframes natively when a user has opted for
The light mode
(Data Saving Mode) in Chrome for Android.
Basic mode is commonly used in regions of the world where the quality of the network connection and data plans are not the best. Every byte is important, and therefore lazy-loading iframes have the potential to make a significant difference for these users.
Origins can detect what percentage of your traffic is coming from basic mode users by checking the navigator.connection.saveData
property, which is part of the NetworkInformation
API.
Can I lazy load iframes across multiple browsers? Yes
Native iframe lazy loading can be applied as a progressive enhancement. Supported browsers loading = lazy
in iframes it will lazy load the iframe, while the loading
The attribute will be safely ignored in browsers that don't support it yet.
It is also possible to lazy load off-screen iframes using the JavaScript library lazysizes. This may be desirable if:
- require more custom lazy loading thresholds than native lazy loading currently offers
- We want to provide users with a consistent iframe lazy loading experience across browsers.
<script src="lazysizes.min.js" async></script>
<iframe frameborder="0"
class="lazyload"
allowfullscreen=""
width="600"
height="400"
data-src="//www.youtube.com/embed/ZfV-aYdU4uE">
</iframe>
Use the following pattern to detect lazy loading function and get lazy sizes when it is not available:
<iframe frameborder="0"
class="lazyload"
loading="lazy"
allowfullscreen=""
width="600"
height="400"
data-src="//www.youtube.com/embed/ZfV-aYdU4uE">
</iframe>
<script>
if ('loading' in HTMLIFrameElement.prototype) {
const iframes = document.querySelectorAll('iframe[loading="lazy"]');
iframes.forEach(iframe => {
iframe.src = iframe.dataset.src;
});
} else {
const script = document.createElement('script');
script.src =
'https://cdnjs.cloudflare.com/ajax/libs/lazysizes/5.2.2/lazysizes.min.js';
document.body.appendChild(script);
}
</script>
An option for WordPress users
You might have a lot of iframes scattered over years of posting content on a WordPress site. Optionally, you can add the following code to your WordPress theme functions.php
file to auto insert loading = "lazy"
to your existing iframes without having to manually update them individually.
Note that Work is also underway on native support for lazy loading iframes in the WordPress core. The following snippet will search for the relevant flags so that once WordPress has the functionality built in, it will no longer manually add the loading = "lazy"
attribute, making sure it is interoperable with those changes and will not result in a duplicate attribute.
function wp_lazy_load_iframes_polyfill( $content ) {
if ( function_exists( 'wp_lazy_loading_enabled' ) && wp_lazy_loading_enabled( 'iframe', 'the_content' ) ) {
return $content;
}return str_replace( '<iframe ', '<iframe loading="lazy" ', $content );
}
add_filter( 'the_content', 'wp_lazy_load_iframes_polyfill' );
If your WordPress site uses caching (hint: it should), don't forget to rebuild your site's cache afterward.
conclusion
Baking in native support for lazy loading iframes makes it much easier for you to improve the performance of your web pages. If you have any comments on native iframe lazy loading feel free to submit a problem to Chrome Bug Tracker.
And in case you missed it, check out web.dev's collection of lazy loading images and videos for more lazy loading ideas.
Our thanks to Dom Farolino, Scott Little, Houssein Djirdeh, Simon Pieters, Kayce Basques, Joe Medley, and Stoyan Stefanov for their reviews.