浏览器中的 iframe 懒加载

浏览器中的 iframe 懒加载

标准化的延迟加载,用于图像的loading属性在 Chrome 76 中登陆,后来又出现在 Firefox 中。我们很高兴与您分享 iframe 的浏览器级延迟加载现已 标准化,并且在基于 Chrome 和 Chromium 的浏览器中也受支持。

<iframe src="https://example.com"
        loading="lazy"
        width="600"
        height="400"></iframe>

iframe 的标准延迟加载延迟了屏幕外 iframe 的加载,直到用户在它们附近滚动为止。这样可以节省数据,加快页面其他部分的加载速度,并减少内存使用量。

为什么我们要延迟加载 iframe?

第三方嵌入涵盖了广泛的用例,从视频播放器到社交媒体帖子再到广告。通常,此内容在用户的视口中不会立即可见。相反,只有当他们向下滚动页面时才可以看到它。尽管如此,即使用户不滚动到它,用户也要为每帧支付下载数据和昂贵的 JavaScript 的费用。

根据 Chrome 浏览器针对 Data Saver 用户自动延迟加载屏幕外 iframe 的研究,延迟加载 iframe 可以节省 2-3%的数据量中位数,中位数可减少 1-2%的首次内容绘画,以及 2%的首次输入延迟( FID)的改善达到第 95 个百分点。

iframe 的内置延迟加载如何工作?

loading属性允许浏览器推迟加载屏幕外 iframe 和图像,直到用户在它们附近滚动为止。loading支持三个值:

  • lazy:是延迟加载的理想选择。
  • eager:不是延迟加载的理想选择。立即加载。
  • auto:浏览器将确定是否延迟加载。

auto目前是非标准值,但今天是 Chrome 中的默认值。Chrome 打算将有关此值的建议引入标准表。

loading在 iframe 上使用属性的工作方式如下:

<!-- Lazy-load the iframe -->
<iframe src="https://example.com" 
        loading="lazy" 
        width="600" 
        height="400"></iframe>

<!-- Eagerly load the iframe -->
<iframe src="https://example.com" 
        width="600" 
        height="400"></iframe>

<!-- or use loading="eager" to opt out of automatic 
lazy-loading in Lite Mode -->
<iframe src="https://example.com" 
        loading="eager" 
        width="600" 
        height="400"></iframe>

完全不指定属性将与明确渴望加载资源产生相同的影响,除了精简模式 用户外,Chrome 将使用该auto值来决定是否应延迟加载该资源。

如果您需要通过 JavaScript 动态创建 iframe,iframe.loading = 'lazy'则还支持在元素上进行设置 :

var iframe = document.createElement('iframe');
iframe.src = 'https://example.com';
iframe.loading = 'lazy';
document.body.appendChild(iframe);

iframe 的特定延迟加载行为

根据是否隐藏 iframe,loading 属性对 iframe 的影响与对图像的影响不同。(隐藏的 iframe 通常用于分析或交流目的。)Chrome 使用以下条件来确定 iframe 是否被隐藏:

  • iframe 的宽度和高度4px小于或等于。
  • display: nonevisibility: hidden已应用。
  • 使用负 X 或 Y 定位将 iframe 置于屏幕外。
  • 此标准适用于loading=lazyloading=auto

如果 iframe 满足以下任何条件,Chrome 会认为它是隐藏的,并且在大多数情况下不会延迟加载。未隐藏的 iframe 仅在它们处于加载距离阈值内时才会加载。Chrome 显示了仍在抓取的延迟加载 iframe 的占位符。

延迟加载流行的 iframe 嵌入可能会带来什么影响?

如果我们可以整体上改变网络,以使延迟加载屏幕外 iframe 成为默认设置,该怎么办?它看起来像这样:

延迟加载 YouTube 视频嵌入(在初始页面加载时节省〜500KB):

<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>

轶事:当我们切换为 Chrome.com 的延迟加载 YouTube 嵌入代码时,与在移动设备上进行互动的速度相比,我们节省了 10 秒钟的时间。我在 YouTube 上打开了一个内部错误,讨论添加 loading=lazy到其嵌入代码中的问题。

延迟加载 Instagram 嵌入(初始加载时压缩 > 100KB 的压缩文件):

Instagram 嵌入提供了一个标记块和一个脚本,该脚本将 iframe 注入您的页面。延迟加载此 iframe 可避免必须加载嵌入所需的所有脚本。鉴于大多数文章中此类嵌入通常显示在视口下方,因此这似乎是延迟加载其 iframe 的合理选择。

延迟加载 Spotify 嵌入(初始加载时节省 514KB):

<iframe src="https://open.spotify.com/embed/album/1DFixLWuPkv3KT3TnV35m3" 
        loading="lazy"
        width="300" 
        height="380" 
        frameborder="0" 
        allowtransparency="true" 
        allow="encrypted-media"></iframe>

等等,浏览器难道不能自动延迟加载屏幕外 iframe 吗?

他们当然可以。在 Chrome 77 中,Chrome 添加了对用户 在 Android 版 Chrome 中选择进入精简模式(数据保护程序模式)时自动延迟加载屏幕外图像和 iframe 的支持 。

精简模式通常用于网络连接质量和数据计划不是最好的地区。每个字节都很重要,因此延迟加载 iframe 可能会对这些用户产生有意义的影响。

Origins 可以通过检查navigator.connection.saveData属性(NetworkInformationAPI 的一部分)来检测来自精简模式用户的流量百分比。

frame 延迟加载可以用作渐进增强功能。支持loading=lazyiframe 的浏览器将延迟加载 iframe,而在loading尚不支持 iframe 的浏览器中将安全地忽略该属性。

也可以使用 lazysizes JavaScript 库来延迟加载屏幕外 iframe 。如果您满足以下条件,这可能是理想的:

  • 与目前标准的延迟加载相比,需要更多的自定义延迟加载阈值
  • 希望为用户提供跨浏览器一致的 iframe 延迟加载体验
<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>

使用以下模式来检测延迟加载并在不可用时获取延迟大小:

<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 {
    // 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);
  }

</script>

为 WordPress 用户的选项

您可能在 WordPress 网站中添加了许多 iframe,这些 iframe 分散了价值多年的帖子内容。您可以选择将以下代码添加到 WordPress 主题functions.php文件中,以自动插入loading="lazy"到现有的 iframe 中,而无需分别手动更新它们。

请注意,WordPress 核心中也正在对延迟加载 iframe 提供本机支持。以下代码段将检查相关标志,以便一旦 WordPress 具有内置功能,它将不再手动添加该loading="lazy"属性,从而确保该属性可与那些更改互操作并且不会导致重复的属性。

// TODO: Remove once https://core.trac.wordpress.org/ticket/50756 lands.
function wp_lazy_load_iframes_polyfill( $content ) {
	// If WP core lazy-loads iframes, skip this manual implementation.
	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' );