Perhaps I am wrong, but I think that many people are unaware of native lazy loading of iframes. I think it has flown under the radar. I guess lazy loading of images was more front and center because images are the most popular resource type on the web and make up the majority of the weight of a typical webpage. But what about the venerable
Before we go further, it is worthwhile stating what an
iframe is. It is not an Apple product! 😉
An iframe is not lightweight! Every
iframe in a page requires increased memory and some computing resources. If you overdo the usage of iframes in a page, it can led to performance problems. So, if we can avoid loading iframes initially through lazy loading, we can improve the speed of the initial page load.
The good news is that similar to images, the
loading attribute is used on the
iframe element for lazy loading. To mark an
iframe as a canidate for lazy loading, just add
loading=lazy to the opening tag.
<iframe loading="lazy" width="560" height="315"
title="A lazy loaded iframe bruh">
The supported values for the
loading attribute are:
lazy: Defer loading of the resource until it reaches a calculated distance from the viewport.
eager: This is the default loading behavior of the browser. This is the same as not including the attribute and means the iframe is loaded regardless of where it’s located on the page. While this is the default, it can be useful to explicitly set this if your tooling automatically adds
In the last month, it has landed in all 3 browser engines.
I suggest that you follow the same advice given for images, and avoid adding
loading=lazy to iframes that are in the viewport when a page loads.
If you want to roll out lazy loading iframes on a website, I would run some A/B tests to verify everything is as you expect. There may be a difference between using
loading=eager and omitting the attribute altogether for iframes that are in the initial viewport. It is was just added for Safari and Firefox, so a bit of caution is wise for now.
To gauge the impact, I did an A/B test on my blog. I picked my biggest blog post which is my Stranger Things animation tutorial. It is a huge post that has 14 codepens! 😅 You should avoid making pages like this generally!
I use an
iframe embed for codepens. All the iframes are in the page from the get go, no scripts adds them on the client side.
I did the performance testing using WebPageTest. This is a lab test, so don’t take the results too literally as it does not reflect real world usage. It does 3 runs and takes the median result of the runs to reduce variability. In the first test, I tested without lazy loading on the codepens. In the second test, I added lazy loading to 13 out of the 14 codepens - I excluded the first one. I used the same conditions for both tests, testing on my public website.
|First Contentful Paint
|Total Blocking Time
|Without lazy loading
|With lazy loading
As you can see, it has a major impact on a large page. It cuts First Contentful Paint by approxmiately 15%, that can push your Core Web Vitals score towards the green. The biggest change is the Total Blocking Time – from 10 seconds to 1 second – having a page being unresponsive to input for that period is unacceptable! And page weight is down 50%. This page would really suck on low-powered devices without lazy loading!
I think it is useful to see the impact on a large page to grasp the magnitude of the potential improvement. On a typical page with a couple of iframes, the performance boost will be a lot more modest of course, but it does add up. The key takeaway is that the bang for buck is high – the effort is low to add an attribute to an element.
The phrase graceful degradation still doesn’t sit with me comfortably, you can consider native lazy loading as a toll-free addition. Browsers that do not support the
loading attribute will ignore its presence. While browsers that support it, will give you a performance bump. There is no negative impact, with the exception of browser bugs.
Probably the number one usage of iframes on websites is from third-party embeds such as YouTube videos, tweets (from X, formerly Twitter), code demos (codepen, JSFiddle, and so on), and many more. It might be worthwhile reviewing them with lazy loading in mind.
Some services like YouTube just offer an
iframe embed, while others offer a HTML embed. The HTML embed is usally a
div with some data attributes, and has a script that transforms the
div into an
iframe. The script can do other stuff too of course!
I had at look at a few and found that:
It easier to use a component or shortcode for embeds on websites. Then you can update the component to provide better defaults and add new features such as lazy loading. No need to do a global find-and-replace with some funky regex to get all instances to do the same thing.
Since iframes are taxing on page performance, a significant performance saving can be made if you lazy load them. It is low-hanging fruit for improving perf. In my test, on my biggest blog post with (too) many iframes - adding lazy loading cut First Contentful Paint by 15%, reduced Total Blocking Time by 90%, and shred page weight by 50%.
You use lazy loading on iframes the exact same way as do for images. You use the
loading attribute, just add
loading=lazy to the opening tag.
It is supported by all 3 browser engines now. The
loading attribute will degrade gracefully – browsers that do not support it will ignore its presence.
I would recommend that you follow the same advice given for images, and avoid adding
loading=lazy to iframes that are in the viewport when a page loads. Doing so may have a negative impact on perf.
So, go ahead, make the web faster! Or are you too lazy?🦥😉