---
layout: post
title: Пришло время отложенной загрузки фреймов вне экрана!
subhead: Встроенная отложенная загрузка для окон iframe на уровне браузера
authors:
  - addyosmani
date: 2020-07-24
updated: 2022-08-15
hero: image/admin/dMCW2Qqi5Qp2DB3w4DyE.png
alt: Схематическое изображение телефона, на котором идет загрузка рисунка и ресурсов
description: В этой статье рассказывается об атрибуте loading и о том, как его можно использовать, чтобы управлять загрузкой фреймов.
tags:
  - blog
  - performance
  - memory
feedback:
  - api
---

[Унифицированная отложенная загрузка изображений](/browser-level-image-lazy-loading/) появилась в Chrome 76 благодаря атрибуту `loading`, а затем была реализована и в Firefox. Мы рады сообщить, что **отложенная загрузка iframe на уровне браузера** теперь [унифицирована](https://github.com/whatwg/html/pull/5579) и поддерживается в Chrome и браузерах на основе Chromium.

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

Реализованный функционал откладывает загрузку внеэкранных iframe до тех пор, пока пользователь не прокрутит страницу до них. Это экономит данные, ускоряет загрузку других частей страницы и снижает использование памяти.

В этой [демонстрации](https://lazy-load.netlify.app/iframes/) `<iframe loading=lazy>` показана отложенная загрузка встраиваемых видео:

<figure data-size="full">
  <video controls autoplay loop muted>
    <source src="https://storage.googleapis.com/web-dev-assets/iframe-lazy-loading/lazyload-iframes-compressed.webm" type="video/webm">
    <source src="https://storage.googleapis.com/web-dev-assets/iframe-lazy-loading/lazyload-iframes-compressed.mp4" type="video/mp4">
  </source></source></video></figure>

### Зачем нужно использовать отложенную загрузку окон iframe?

Сторонние встраивания охватывают широкий спектр вариантов использования: от видеоплееров до сообщений в социальных сетях и рекламы. Часто это содержимое не сразу видно в окне просмотра пользователя. Скорее, оно отображается, лишь когда пользователи прокручивают страницу дальше. Несмотря на это, пользователи теряют время на загрузку данных и дорогостоящее выполнение JavaScript для каждого фрейма, даже если прокрутка до него не доходит.

<figure>{% Img src="image/tcFciHGuF3MxnTr1y5ue01OGLBn2/xqZMRuULxbz6DVXNP8ea.png", alt="Экономия данных за счет использования отложенной загрузки iframe. В этом примере при активной загрузке скачивается 3 МБ, в то время как при отложенной загрузке не скачивается ничего, пока пользователь не переместится ближе к iframe.", width="800", height="460" %}</figure>

Согласно проведенному Chrome исследованию [автоматической отложенной загрузки закадровых iframe для пользователей Data Saver](https://blog.chromium.org/2019/10/automatically-lazy-loading-offscreen.html), отложенная загрузка фреймов может привести к экономии 2-3% данных в срединном значении, сокращению [First Contentful Paint](/fcp/) на 1-2% по медиане и улучшению [First Input Delay](/fid/) (FID) на 2% в 95-м процентиле.

### Как работает встроенная отложенная загрузка для iframe?

Атрибут `loading` позволяет браузеру отложить загрузку окон iframe и изображений за пределами экрана до тех пор, пока пользователи не прокрутят экран до них. `loading` поддерживает два значения:

- `lazy`: подходящее значение для отложенной загрузки.
- `eager`: неподходящее значение для отложенной загрузки. Загрузка выполняется сразу.

Использование атрибута `loading` в окнах iframe работает следующим образом:

```html
<!-- Отложенная загрузка iframe -->
<iframe src="https://example.com"
        loading="lazy"
        width="600"
        height="400"></iframe>

<!-- Немедленная загрузка iframe -->
<iframe src="https://example.com"
        width="600"
        height="400"></iframe>

<!-- или использование loading="eager", чтобы избежать автоматической отложенной загрузки в Lite-режиме -->
<iframe src="https://example.com"
        loading="eager"
        width="600"
        height="400"></iframe>
```

Если вовсе не указывать атрибут, эффект будет аналогичным явной немедленной загрузке ресурса, за исключением [пользователей облегченного режима](https://blog.chromium.org/2019/04/data-saver-is-now-lite-mode.html), где Chrome будет использовать значение `auto`, чтобы решить, следует ли выполнять отложенную загрузку.

Если вам нужно *динамически* создавать фреймы с помощью JavaScript, также [поддерживается](https://bugs.chromium.org/p/chromium/issues/detail?id=993273) `iframe.loading = 'lazy'` для элемента:

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

#### Отложенная загрузка в зависимости от iframe

Атрибут loading работает для встроенных фреймов иначе, чем для изображений, так как в учет берется то, является ли iframe скрытым. (Скрытые iframe часто используются для аналитических или коммуникационных целей.) Chrome использует следующие критерии для определения того, является ли iframe скрытым:

- Ширина и высота iframe не более `4px`.
- Применяются `display: none` или `visibility: hidden`.
- iframe помещается за пределы экрана с использованием отрицательного позиционирования по оси X или Y.
- Этот критерий применяется как к `loading=lazy`, так и к `loading=auto`.

Если iframe соответствует любому из этих условий, Chrome считает его скрытым и в большинстве случаев не загружает его в отложенном режиме. Не скрытые окна iframe загружаются только тогда, когда они находятся в пределах [порогового расстояния для загрузки](/browser-level-image-lazy-loading/#load-in-distance-threshold). Для встроенных фреймов, которые всё еще загружаются в режиме отложенной загрузки, отображается плейсхолдер.

### Какой эффект можно наблюдать при отложенной загрузке популярных встраиваемых iframe?

Что, если бы мы могли изменить Интернет в целом так, чтобы по умолчанию использовалась отложенная загрузка фреймов за пределами экрана? Это выглядело бы примерно так:

Отложенная загрузка встроенных видео YouTube (экономия ≈500 КБ при начальной загрузке страницы):

```html/1
<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>
```

**Случай из практики:** перейдя на отложенную загрузку встраиваемых файлов YouTube для Chrome.com, мы сэкономили 10 секунд для установления интерактивности наших страницы на мобильных устройствах. Я открыл внутренний дефект, чтобы обсудить с YouTube добавление `loading=lazy` в его код для встраивания.

<figure>{% Img src="image/tcFciHGuF3MxnTr1y5ue01OGLBn2/HQkwBgEoyiZsiOaPyz8v.png", alt="Chrome.com добился сокращения TTI на 10 секунд за счет отложенной загрузки фреймов за пределами экрана для встроенного видео YouTube", width="800", height="460" %}</figure>

{% Aside %} Если вы ищете более эффективные способы загрузить вставки YouTube, вас может заинтересовать [компонент YouTube lite](https://github.com/paulirish/lite-youtube-embed). {% endAside %}

**Отложенная загрузка вставок Instagram (экономия &gt;100 КБ в сжатом виде при начальной загрузке):**

Вставки Instagram содержат блок разметки и скрипт, который вставляет iframe на вашу страницу. Отложенная загрузка этого iframe позволяет избежать загрузки всего скрипта, необходимого для встраивания. Учитывая, что такие вставки отображаются под окном просмотра в большинстве статей, такой подход выглядит разумным для отложенной загрузки их iframe.

**Отложенная загрузка вставок Spotify (экономия 514 КБ при начальной загрузке):**

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

Приведенные выше вставки иллюстрируют потенциальные преимущества отложенной загрузки iframe для медиаконтента, однако есть вероятность, что эти преимущества будут справедливы и для рекламы.

### Пример использования: отложенная загрузка социальных плагинов Facebook

*Социальные плагины* Facebook позволяют разработчикам встраивать контент Facebook на свои веб-страницы. Предлагается ряд таких подключаемых модулей, например, встроенные публикации, фотографии, видео, комментарии… Самым популярным является [подключаемый модуль «Нравится»](https://developers.facebook.com/docs/plugins/like-button/) — кнопка, которая показывает количество тех, кому понравилась страница. По умолчанию встраивание плагина «Нравится» на веб-страницу (с использованием FB JSSDK) требует ≈215 КБ ресурсов, из которых 197 КБ составляет JavaScript. Во многих случаях плагин может появляться в конце статьи или ближе к концу страницы, поэтому его активная загрузка за пределами экрана может быть нерациональной.

<figure>{% Img src="image/admin/fdy8o61jxPN560IkF2Ne.png", alt="Кнопка «Нравится» на Facebook", width="800", height="71" %}</figure>

Благодаря инженеру Стояну Стефанову [все социальные плагины Facebook](https://developers.facebook.com/docs/plugins/like-button#settings) теперь поддерживают унифицированную отложенную загрузку iframe. Разработчики, которые выбрали отложенную загрузку с помощью конфигурации плагина `data-lazy`, теперь смогут отложить загрузку контента до тех пор, пока пользователь не прокрутит страницу до нужного места. Это обеспечивает полный функционал встроенных элементов для пользователей, которым они нужны, и экономит данные для тех, кто не прокручивает страницу до конца. Мы надеемся, что это лишь первая из многих вставок, при эксплуатации которых будет применяться унифицированная отложенная загрузка iframe.

### Могу ли я выполнять отложенную загрузку окон iframe кроссбраузерно? Да

Отложенная загрузка iframe может применяться как прогрессивное усовершенствование. Браузеры, которые поддерживают `loading=lazy` для iframe, будут откладывать загрузку iframe, при этом атрибут `loading` будет просто игнорироваться в браузерах, которые его еще не поддерживают.

Также можно отложить загрузку фреймов вне экрана с помощью библиотеки JavaScript [lazysizes](/use-lazysizes-to-lazyload-images/). Это может понадобиться, если вам:

- требуется большее число настраиваемых порогов отложенной загрузки, чем то, что в настоящее время предлагает унифицированная отложенная загрузка
- нужно обеспечить пользователям единообразную отложенную загрузку iframe во всех браузерах.

```html/3
<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>
```

Используйте следующий шаблон, чтобы обнаруживать функцию отложенной загрузки и получать lazysizes, когда она недоступна:

```html/2
<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 {
    // Динамический импорт библиотеки LazySizes
    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 }

У вас может быть масса фреймов, разбросанных по куче публикаций за разные годы на сайте WordPress. При желании вы можете добавить следующий код в файл `functions.php` своей WordPress-темы, чтобы автоматически вставлять `loading="lazy"` в существующие фреймы без необходимости вручную обновлять каждый из них по отдельности.

Обратите внимание, что [для ядра WordPress также ведутся работы над поддержкой отложенной загрузки iframe на уровне браузера](https://core.trac.wordpress.org/ticket/50756). Следующий фрагмент кода проверит наличие соответствующих флагов, чтобы после того, как WordPress получит встроенную функциональность, он перестал вручную добавлять атрибут `loading="lazy"`. Так будет гарантирована совместимость с этими изменениями и атрибут не будет дублироваться.

```php
// СДЕЛАТЬ: Удалить, когда появится https://core.trac.wordpress.org/ticket/50756.
function wp_lazy_load_iframes_polyfill( $content ) {
	// Если ядро WP загружает iframe отложенно, эту ручную реализацию нужно пропустить.
	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' );
```

Если ваш сайт WordPress использует кеширование (подсказка: он должен), не забудьте впоследствии перестроить кеш вашего сайта.

### Заключение

Наличие унифицированной поддержки отложенной загрузки iframe значительно упрощает повышение производительности ваших веб-страниц. Если у вас есть какие-либо отзывы, отправьте сообщение в [Chromium Bug Tracker](https://bugs.chromium.org/p/chromium/issues/entry?components=Blink%3ELoader%3ELazyLoad).

И, если вы вдруг пропустили, ознакомьтесь с [коллекцией отложенной загрузки изображений и видео](/fast/#lazy-load-images-and-video) web.dev, чтобы получить больше идей для отложенной загрузки.

*Выражаем благодарность Доминику Фаролино, Скотту Литтлу, Хуссейну Джирде, Саймону Питерсу, Кэйси Баскесу, Джо Медли и Стояну Стефанову за их рецензии.*
