HomeMethod

Knowledge

Web VitalsTechniquesSnippetsAnswersImpactsBottlenecks

Lazyload Iframes

Defer iFrame loading until the embed nears the viewport — either via loading="lazy" or IntersectionObserver.

Each ring is a metric this technique moves.

Impact grade, A+ to D: how much of the Lighthouse score this technique can move. Unaffected: CLS, TTFB.

The Problem

A single YouTube or Google Maps iFrame can fire dozens of sub-requests and execute several hundred kilobytes of third-party JavaScript. When these embeds load at page start they compete with the critical rendering path, blocking the main thread, consuming bandwidth needed for the LCP element, and delaying the page becoming interactive — all for content the user may never scroll to.

Performance Impact

LCP

High

deferred iFrame JavaScript and network requests stop competing with above-the-fold resources

TBT

High

heavy third-party scripts inside iFrames execute after the main thread is free

FCP

Medium

fewer resources competing during the initial render phase

SI

third-party frame resource chains are deferred; their heavy payloads do not slow above-fold visual population

How it works

  1. 01

    Native loading="lazy" attribute

    Adding loading="lazy" to an <iframe> tag activates the browser’s built-in deferred loading. The browser decides the exact viewport distance threshold. WordPress Core applies this automatically to oEmbed iFrames (YouTube, Vimeo, etc.) since WP 5.7 when width and height are present.

  2. 02

    Manual iFrames and third-party shortcodes

    iFrames added via custom HTML blocks, theme templates, or plugins that do not go through WordPress’s oEmbed pipeline need the attribute added manually. A PHP filter on the_content can inject loading="lazy" into any <iframe> that already has explicit dimensions.

  3. 03

    JavaScript fallback for complex cases

    For custom placeholders (e.g. a video poster image that reveals the embed on click — a “facade” pattern) or when browsers need a specific loading threshold, JavaScript with IntersectionObserver swaps a data-src value into src when the element approaches the viewport.

  4. 04

    Width and height are non-negotiable

    Without explicit dimensions the browser cannot reserve space, causing a layout shift when the iFrame loads. Native loading="lazy" also only activates reliably when both attributes are present.

HTML — native lazy attribute

Code
<iframe
  src="https://www.youtube.com/embed/your-video-id"
  width="560"
  height="315"
  loading="lazy"
  title="YouTube video player"
  frameborder="0"
  allowfullscreen>
</iframe>

width and height attributes are required for loading="lazy" to work reliably and to prevent layout shifts.

PHP — add loading="lazy" via filter

Code
<?php
function add_lazy_iframes( $content ) {
  if ( is_admin() ) return $content;

  return preg_replace(
    '/<iframe(?![^>]*loading=)([^>]*)(width=["']\d+["'][^>]*height=["']\d+["']|height=["']\d+["'][^>]*width=["']\d+["'])[^>]*>/i',
    '<iframe loading="lazy"$1$2>',
    $content
  );
}
add_filter( 'the_content', 'add_lazy_iframes', 20 );

This adds loading="lazy" only to iFrames that already have both width and height attributes, avoiding empty-dimension iFrames that would cause layout shifts.

Limitations

  • An iFrame that is visible on initial load — especially one that is the LCP element — should not be lazy-loaded. Deferring it delays the most important visible content.
  • Layout shifts (CLS) occur if width and height attributes are missing — the browser cannot reserve space before the iFrame loads.
  • Browser thresholds for when lazy loading triggers vary between vendors — content may appear to load slightly earlier or later depending on the browser.
  • JavaScript-based solutions do not work when JS is disabled; native loading="lazy" has no such dependency.

Common Mistakes

Applying loading=”lazy” to an above-the-fold embed

For hero videos or maps that are part of the initial viewport, load eagerly. The lazy attribute is only beneficial for iFrames the user has not yet scrolled to.

Omitting width and height attributes

Always specify explicit dimensions. Without them, native lazy loading may not activate, and the iFrame will cause a CLS hit when it finally loads.

Building custom JavaScript when the native attribute is sufficient

For most WordPress oEmbeds, WP Core already handles it. Check first before adding a plugin or writing a script that duplicates the behaviour.

Test this techniqueScripts DiagnosticsRun the tool

Need help applying this to your site?

Targeted fixes, not guesswork. We identify which techniques move the needle for your specific WordPress stack.

Start an Engagement
Support our family now