An embedded video or map looks like one line of HTML, but the browser treats it as a whole second web page. It downloads that page's HTML, scripts, fonts and images, and starts running its JavaScript, even if the visitor never scrolls down to it. A few embeds on a long article can add a large amount of transfer and work to a page that is otherwise light.
This guide shows you how to lazy load an iframe: tell the browser to wait until the embed is near the screen before it fetches anything. You will also see what to do when the embed is the main content of the page, how to reserve space so the page does not jump, how to go one step further with a click-to-load facade, and how to confirm that search engines can still see what you embedded. It is written for site owners and developers who can edit page templates or a CMS "custom HTML" block.
By the end you will have embeds that load when they are needed, a layout that stays stable while they arrive, and a short test routine you can repeat after each template change.
Before you begin
You need the ability to edit the HTML of the pages that contain embeds. In a CMS this is usually a "custom HTML" or "embed code" block; in a theme it is a template file. Make a copy of the page or template before editing, and note the current page weight and the number of requests in your browser's Network panel so you have something to compare against.
Make a list of every embed type on the site: video players, maps, booking widgets, social posts, forms, chat panels. Not all of them are good candidates. Plan on about an hour for a small site. The change itself is small; most of the time goes on checking each template.
One caution up front: lazy loading reduces work that happens before the visitor reaches the embed. It does not make the embedded service itself faster, and it does not promise any particular score or ranking change.
How iframe lazy loading works
The <iframe> element has a loading attribute. According to MDN, it has two values: eager, which loads the frame immediately and is the default, and lazy, which defers loading until the frame reaches a distance from the visible viewport that the browser calculates. The browser decides that distance; there is no number you can set in HTML. MDN also notes that deferral only happens when JavaScript is enabled, which is an anti-tracking measure. Without scripting, the frame loads normally.
web.dev lists browser support as Chrome 77, Edge 79, Firefox 121 and Safari 16.4 for iframe lazy loading. A browser that does not understand the attribute ignores it and loads the frame as usual, so adding it is low risk. Nothing breaks; you just do not get the saving in that browser.
Google's guidance on lazy loading and Search lists built-in browser lazy loading for images and iframes among the suitable methods. It also says Google Search does not interact with your page, so content that appears only after a scroll or click handler fires may never be seen by the crawler. The goal is that everything relevant loads when it is visible in the viewport, without needing a user action.
Step-by-step instructions
Step 1: Find and rank your embeds
Open a typical page with developer tools, go to the Network panel and filter by "Doc" to see the iframes. Reload and note how much each one transfers. Do the same on your longest pages and on your highest-traffic templates.
Then sort the embeds into two groups. Frames that sit below the first screen of content on most devices are good candidates. A frame that is the main point of the page, such as a video at the top of a video page, is not.
web.dev uses the same split: offscreen iframes are good candidates for lazy, and frames that should load right away should stay eager. Google also warns against lazy loading content that people see immediately, because it can delay that content.
What success looks like: You have a list of embeds, each marked "below the fold, lazy load" or "visible at once, leave eager", with the transfer size of each.
Step 2: Add loading="lazy" to below-the-fold iframes
Here is a typical YouTube embed with the attribute added:
<iframe
src="https://www.youtube-nocookie.com/embed/VIDEO_ID"
title="How to renew an SSL certificate (7 minute walkthrough)"
width="560"
height="315"
loading="lazy"
allow="encrypted-media; picture-in-picture"
allowfullscreen></iframe>
Replace VIDEO_ID with the real ID from the video's Share and Embed dialog. YouTube's own help page explains that you can switch the embed domain from www.youtube.com to www.youtube-nocookie.com for privacy-enhanced mode, in which views are not used to personalize the viewer's YouTube experience. That is a privacy choice, not a speed feature, so decide on it separately.
The same attribute works for map frames, booking widgets and other iframes. For frames you create in script, set the property before adding the element:
const frame = document.createElement('iframe');
frame.loading = 'lazy';
frame.src = 'https://example.com/widget';
frame.title = 'Opening hours widget';
document.querySelector('#widget-slot').append(frame);
In a CMS, paste the attribute into the embed code block. Some page builders add their own lazy loading option; if the frame already carries the attribute, do not add it twice.
What success looks like: In the page source (View Source, not the Elements panel), the iframe has loading="lazy". When you load the page with the Network panel open and do not scroll, the embed's requests are absent. Scroll down and they appear shortly before the embed comes into view.
Step 3: Give every iframe a title and reserve its space
Two small details separate a good embed from a problem one.
First, add a concise title that describes what is inside. MDN says people using screen readers rely on the title to label the frame's content; without it they have to move into the frame to find out what it is. "YouTube video player" is weak. A description of the actual video or map is better.
Second, reserve the space the frame will take, so the text below does not jump when it loads. web.dev's layout shift guidance says embeds often cannot know their size before they load, and recommends reserving room with a min-height or the aspect-ratio property. For a 16:9 video that looks like this:
.embed-video {
width: 100%;
max-width: 560px;
aspect-ratio: 16 / 9;
}
.embed-video iframe {
width: 100%;
height: 100%;
border: 0;
}
<div class="embed-video">
<iframe src="https://www.youtube-nocookie.com/embed/VIDEO_ID"
title="How to renew an SSL certificate"
loading="lazy" allowfullscreen></iframe>
</div>
The same web.dev page advises not collapsing the reserved space if nothing loads, since removing space can shift content as much as adding it. Our guide on reducing Cumulative Layout Shift covers the wider picture.
What success looks like: With a throttled connection, the page shows an empty box of the right size, and the text below does not move when the embed appears.
Step 4: Keep above-the-fold embeds eager
If an embed is the main content of the page or sits in the first screenful, remove the lazy attribute (or set loading="eager"). Lazy loading content the visitor sees at once only delays it. If the embed is also your largest visible element, it may be what the Largest Contentful Paint metric measures. a deferred hero embed works against you. See fixing Largest Contentful Paint for how to find the LCP element.
Do not guess here. Run the page in Lighthouse or the Performance panel and see which element is reported. Then decide per template.
What success looks like: The visible-at-once embeds load without the lazy attribute, and the LCP element on each key template is the one you expect.
Step 5: Use a click-to-load facade for heavy players
Native lazy loading still loads the whole player once it is near the screen. A facade goes further: the page shows a lightweight placeholder, usually a preview image with a play button, and swaps in the real iframe only when the visitor clicks. web.dev mentions the lite YouTube embed component as a more efficient way to load YouTube embeds.
A minimal hand-written version uses a real button, so it works with a keyboard:
<button class="video-facade" type="button"
data-src="https://www.youtube-nocookie.com/embed/VIDEO_ID?autoplay=1"
data-title="How to renew an SSL certificate"
aria-label="Play video: How to renew an SSL certificate">
<img src="/img/renew-ssl-poster.jpg" width="560" height="315"
alt="" loading="lazy">
</button>
document.querySelectorAll('.video-facade').forEach(function (btn) {
btn.addEventListener('click', function () {
var f = document.createElement('iframe');
f.src = btn.dataset.src;
f.title = btn.dataset.title;
f.width = 560;
f.height = 315;
f.allow = 'autoplay; encrypted-media; picture-in-picture';
f.setAttribute('allowfullscreen', '');
btn.replaceWith(f);
});
});
YouTube's help page documents autoplay=1 for the embed URL, which is why the player can start right after the click. Browsers can still limit autoplay, so test it.
The trade-off matters. A facade means the visitor needs two actions to watch, and a crawler never sees the real iframe because it does not click. If the video is important to search, make sure the page has a text summary or transcript, and consider whether a plain lazy iframe is enough. A facade on a page where the video is a side note is a good fit. Our guide on third-party scripts and performance explains how to weigh the cost of other embedded services.
What success looks like: The placeholder is keyboard focusable, announces what it does, and clicking it replaces itself with a working player.
Step 6: Check what search engines can see
Google's lazy loading guidance recommends using the URL Inspection tool in Search Console to confirm that content loads, and checking the rendered HTML. Run the live test on a page with embeds and review the rendered HTML for the iframe element. If you used native loading="lazy", the iframe tag should be there with its src.
Remember what an iframe is: a separate document. Text inside a video or a map is not part of your page's own content. If you want the page to be understood for its topic, put the key facts, a short description or a transcript in the page itself, in regular HTML.
What success looks like: The rendered HTML shows the iframe tags, and the information you care about for search is also present as normal text on the page.
Final verification checklist
- Every embed on your key templates is listed and marked lazy or eager.
- Below-the-fold iframes show
loading="lazy"in the page source. - Embeds visible on first load do not carry
loading="lazy". - With the Network panel open and no scrolling, lazy embeds make no requests.
- Each iframe has a specific, short
title. - Each embed has reserved space through
aspect-ratioormin-height, and the page does not jump as it loads. - Any facade can be used with a keyboard and has an accessible name.
- URL Inspection's rendered HTML shows the iframes, and key information is also in plain page text.
- You compared transfer size and request count before and after.
Common mistakes to avoid
- Lazy loading the embed at the top of the page. The visitor sees the delay, and it can hurt LCP if the embed is the largest element. Leave first-screen frames eager.
- Reserving no space. The frame appears and pushes the text down. Use
aspect-ratioormin-heightas web.dev describes. - Assuming a facade is visible to crawlers. Crawlers do not click, so they do not see the swapped-in player. Add text content on the page.
- Using the same vague title on every frame. "Video" tells a screen reader user nothing. Describe each frame.
- Relying on a scroll handler you wrote yourself. Google says its crawler does not interact with the page. Prefer the native attribute, or an IntersectionObserver-based approach that loads content when it becomes visible.
- Lazy loading hidden frames used for tracking or messaging. The attribute does not distinguish them. web.dev notes that developers choose what is lazy loaded, so mark only content frames.
- Treating the change as finished without testing. Test on a phone-sized screen, on a slow connection and with the keyboard. Check that autoplay, fullscreen and consent prompts still work.
Frequently asked questions
Is loading="lazy" safe for iframes in every browser?
Browsers that do not support it ignore the attribute and load the frame normally. web.dev lists support in Chrome 77, Edge 79, Firefox 121 and Safari 16.4, so current browsers handle it.
How far from the screen does the browser start loading?
The browser decides. MDN says only that loading is deferred until the frame reaches a calculated distance from the viewport. You cannot set a number in HTML. If you need exact control, you would write your own IntersectionObserver code, with the trade-offs above.
Will lazy loading make my page rank higher?
No, and no guide can promise that. It reduces work done before the visitor needs the embed, which can help loading metrics on pages with several embeds. How a page ranks depends on many other things.
Does Google index text inside my YouTube or map iframe?
Treat the frame as a separate document. Put the information you want associated with your page in your own HTML, such as a heading, a description or a transcript, and do not rely on the iframe's internal content.
Should I lazy load a map?
If the map is below the first screen, yes. If the map is the main reason people visit the page, such as a "find us" page, test it eager first. Some map embeds are heavy, so a static image with a link, or a click-to-load facade, is also a valid choice.
Related guides
- Lazy Loading Images for SEO: Defer Images Without Hiding Them
- Reduce Cumulative Layout Shift (CLS) Step by Step
- Fix Largest Contentful Paint (LCP) on Mobile
- Third-Party Scripts and Performance: Measure and Tame Them
- Improve Lighthouse Performance Without Breaking Your Website
Official references
- https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/iframe
- https://web.dev/articles/iframe-lazy-loading
- https://web.dev/articles/optimize-cls
- https://developers.google.com/search/docs/crawling-indexing/javascript/lazy-loading
- https://support.google.com/youtube/answer/171780
Next step: See how Crawvix checks a website and capture a baseline once scanning opens. This guide provides technical information, not a guarantee of rankings, traffic or index inclusion.
Crawvix Editorial Team
· Published October 29, 2026 · Last updated October 29, 2026 · 11 min read